CSCI 169 Notes — Fortran-90/95/2003/2008

 

http://math.scu.edu/~dsmolars/ma169/notesfortran.html

 

[Trở về trang chủ CSCI 169]

top

Đôi nét của CSCI 169 về –Fortran-90/95/2003/2008


 

Nội dung:

 

 

 

 

 

 

 

 

 

 

 

 

 

 


 

  • A- “ Xin chào cả thế giới!” trong Fortran

Chương trình ví dụ mà mọi người đều biết đến trong Fortran-90/95/2003 có thể viết như sau:

 

 PROGRAM HELLO

    WRITE(6,*) “Hello World!”

 END

 

  •   B- Lịch sử hình thành

FORTRAN ( được viết tắt từ FORmula TRANslation) được phát triển tại IBM New York được dẫn đầu bởi một nhóm lập trình bao gồm John W. Backus (người mà tên tuổi của ông được gắn liền với một mẫu ngôn ngữ mà hiện nay được sử dụng để miêu tả ngôn ngữ máy tính). Nhiều năm trôi qua, Backus làm việc ở cơ sở IBM tại phía nam San Jose.

(Lịch sử hình thành FORTRAN của John Backus có thể được tìm thấy ở http://www.softwarepreservation.org/projects/FORTRAN/paper/p25-backus.pdf. Xem tài liệu tham khảo trang 29 để biết khởi đầu của phần mềm lập trình FORTRAN ở New York).

 

FORTRAN “0” báo cáo – 1954
FORTRAN I trình biên dịch – 1957
FORTRAN II – 1958

—> Thêm vào định nghĩa và yêu cầu của các subroutine
FORTRAN IV – đã được nâng cấp 1960-62, báo cáo tổng kết vào năm 1966
—> Thêm lệnh logical IF, Loại lệnh khai báo Declaration
Phiên bản đặc biệt:
—> Univ. of Waterloo, Ontario — WATFOR
———> WATFIV (WATerloo Fortran IV)
———> WATFIV-S (cấu trúc — ảnh hưởng Pascal)
FORTRAN 77 (or FORTRAN 5) – 1977
—> kế hoạch cho ra mắt phần mềm FORTRAN 88 cuối cùng dẫn đến:
FORTRAN 90 – 1990
—> Thêm vào các chức năng recursion, pointers, modules, local routines
—> Và một số chức năng của ma trận
FORTRAN 95 – 1995
—> Thêm lệnh FORALL và các chức năng khác 
—> sử dụng cho các máy song song
FORTRAN 2003 – 2004
—> có khả năng tương tác với C,
—> các thành phần của kiểu dẫn xuất có thể phân bổ được,
—> Tính năng lập trình hướng về đối tượng cụ thể,
– – – > ví dụ, biến “class”(biến polymorphic)
—> Chức năng pointers,
—> Sơ lược về command line,
—> Và một số cải tiến khác
(Để có thông tin chi tiết của Fortran 2003, có thể tìm đọc 
John Reid, “Cái nhìn tổng thể về Fortran 2003,” ACM Sigplan, Vol. 39:8 [tháng 8 2004], trang 31-38).

John Reid, “Những điều mới mẻ của Fortran 2003” [38 trang PDF file].)

FORTRAN 2008
—> “Coarray Fortran”
—> Cấu trúc DO CONCURRENT và BLOCK.
—> Một số bổ sung và.sửa lỗi khác
(Để có thông tin chi tiết về Fortran 2008, xem: John Reid, “những điều mới mẻ của Fortran 2008” [26 page PDF file].)

 

Xem http://math.scu.edu/~dsmolars/ma60/notesfor2003.html để có thêm thông tin về Fortran 2003 và chương 19 của Sự cần thiết của Fortran 90/95/2003 (http://math.scu.edu/~dsmolars/ma60/briefcont.html) (Danh sách các tính năng của các phiên bản Fortran trước đây mà không còn trong Fortran-95 hoặc Fortran-2003 được liệt kê tại đây).

Fortran-90/95/2003/2008 thường được viết bằng các ký tự không cần thiết phải VIẾT HOA tất cả

 

  • C- Sự phát triển về ngôn ngữ

Fortran (có thể) là ví dụ duy nhất về việc được sử dụng rộng rãi, theo hướng khoa học, ngôn ngữ máy tính đã phát triển gần hơn 50 năm, khi các vấn đề liên quan đến ngôn ngữ lập trình đã kiến nghị các tính năng mới cho các ngôn ngữ, phiên bản Fortran mới sẽ có chúng, trong khi giữ khả năng có thể chạy những chương trình đã được viết ở những phiên bản trước.

 

Đối với các công việc khoa học, trình biên dịch Fortran thường cho code nhanh hơn và có thư viện chương trình rộng lớn hơn những code được viết trong các ngôn ngữ khoa khác.

 

Xem Wikipedia để có trình bày tóm tắt về cách sử dụng phiên bản Fortran hiện tại tại đây: http://en.wikipedia.org/wiki/Fortran

 

  1. D- Sơ lượt

Có hai cách khác nhau để sử dụng code nguồn (chương trình) trong Fortran. Trong các chương trình, cả hai cách đều có thể được sử dụng, nhưng đối với bất kỳ chương trình nào, code chỉ có thể được viết bởi một cách này hoặc cách còn lại

 

  • Cách thứ nhất gọi là Định dạng mã nguồn cố định và đây là cách cũ được sử dụng trước phiên bản Fortran 90/95/2003. Nó dựa trên giới hạn của 80 cột giống thẻ cơ toán. Cho nên, MỖI CỘT TRONG MỖI DÒNG ĐỀU RẤT QUAN TRỌNG!!!
  • Cách còn lại được gọi là Định dạng mã nguồn tự do và cách này thường được sử dụng trong các trình ngôn ngữ mà code có thể đặt ở bất cứ đâu trên hàng mà không bị giới hạn

 

Ở SCU, trên máy chủ chi nhánh Linux Math/CS, math, và rất nhiều hệ thống/trình biên dịch, sự phân biệt giữa 2 cách này được thể hiện bởi ĐUÔI MỞ RỘNG CỦA FILE

 

  • Nếu File có phần đuôi mở rộng là .f hoặc .for, thì tập tin này có chứa code được viết dưới ĐỊNH DẠNG MÃ NGUỒN CỐ ĐỊNH cũ.
  • Nếu File có phần đuô mở rộng là .f90, thì tập tin này gồm có code được viết dưới ĐỊNH DẠNG MÃ NGUỒN TỰ DO mới.

 

  1. Định dạng mã nguồn tự do:

Đối với các chương trình có ĐỊNH DẠNG MÃ NGUỒN TỰ DO (được biết đến như “Phong cách mới” hoặc Fortran-90/95/2003), không có sự hạn chế code được đặt trên một dòng, ngoại trừ việc dòng đó không thể có nhiều hơn 132 ký tự.

 

  • Một câu lệnh có thể bắt đầu từ cột thứ 1 hoặc ở bất kì đâu, và có thể kéo dài tối đa đến cột thứ 132.
  • Một số câu lệnh được phép đặt trên cùng 1 dòng, nếu bạn muốn có nhiều câu lệnh trên cùng 1 dòng, thì giữa chúng phải được ngăn cách bởi dấu chấm phẩy, điều này ở Định dạng mã nguồn cố định cũng có thể thực hiện.
  • Dấu chấm phẩy không cần thiết đặt ở CUỐI dòng vì khi xuống dòng khác thì đó sẽ là một lệnh mới riêng biệt.
  • TRONG ĐỊNH DẠNG TỰ DO, sự tiếp tục của câu lệnh được thể hiện bởi ký tự và,&, ở cuối dòng để câu lệnh được viết tiếp.
  • TRONG ĐỊNH DẠNG TỰ DO, chú thích được bắt đầu bởi dấu chấm than và tiếp tục cho tới khi kết thúc dòng. Một chú thích có thể ở bất cứ dòng nào sau câu lệnh ở dòng trên. Điều này cũng có thể thực hiên ở định dạng cố định.
  • TRONG ĐỊNH DẠNG TỰ DO, khoảng trống rất quan trọng (đối với định dạng cố định thì không thành vấn đề)

 

  1. Định dạng mã nguồn cố định:

Đối với chương trình có ĐỊNH DẠNG MÃ NGUỒN CỐ ĐỊNH (i.e..,”kiểu cũ”), mỗi dòng đều có giới hạn như sau:

(A) Nếu trên dòng có ký tự C hoặc * trong cột thứ 1, thì dòng đó được hiểu là một chú thích phần còn lại của dòng sẽ bị bỏ qua (là phần có thể sử sụng dấu chấm than trong Định dạng mã nguồn tự do nếu dịch bằng trình biên dịch Fortran 90/95/2003)

 

(B) Nếu không thì

 

Cột thư 1-5 dành cho câu lệnh số nhãn (thường để trống).

Cột thứ 6 CHỈ được sử dụng để tiếp nối với dòng trước (nếu có ký tự).

Cột thứ 7-72 dành cho câu lệnh của FORTRAN.

Cột thứ 73-80 bị bỏ qua.

 

GHI CHÚ QUAN TRỌNG: Trong định dạng mã nguồn cố định, vấn đề thường hay xảy ra là việc sử dụng câu lệnh (và biểu thức) quá dài và quên đi “giới hạn” 72 cột, BẤT CỨ gì sau cột “72” đều sẽ bị bỏ qua, cho dù đó là ở giữa hoặc cuối của tên biến, nếu như vậy, có thể trình biên dịch sẽ không đọc được phần kết thúc của câu lệnh quá dài.

 

Tôi không khuyến khích sử dụng định dạng mã nguồn cố định trong khi có khả năng sử dụng định dạng mã nguồn tự do của Fortran-90/95/2003. Tuy nhiên, các bạn nên biết quy tắt quản lý của định dạng mã nguồn cố định vậy nên chúng có thể đọc được những chương trình cũ hơn và theo đó là các giới hạn của phiên bản cũ nếu không truy cập được từ Fortran-90/95/2003. Cho nên, hãy luôn sử dụng đuôi mở rộng là .f90 (hoặc .f95 nếu bạn dùng trình biên dịch Fortran 95)

 

Trong ĐỊNH DẠNG MÃ NGUỒN CỐ ĐỊNH, khoảng trống sẽ bị bỏ qua bởi trình biên dịch (ngoại trừ khi chúng ở giữa mệnh đề output hoặc chuỗi ký tự) nên

 

e.g.,  NUMBER <==> N  UM  BE   R

 

TUY NHIÊN, khoảng trống vẫn ĐƯỢC tính như là các cột bình thường

CHÚ Ý: Thậm chí nếu bạn sử dụng mã nguồn cố định cũ để viết chương trình trong tập tin, thì bạn cũng có thể dùng bất cứ câu lệnh nào cũa Fortran-90/95/2003

 

  1. Các loại khác
  • Mỗi dòng được cho là một câu lệnh riêng biệt trừ phi có ký hiệu của sự tiếp tục! (cho nên xuống dòng mới thường sẽ kết thúc dòng lệnh trên giống như cách mà dấu chấm phẩy sẽ chấm dứt câu lệnh trong C/C++).
  • Cho tới bây giờ và bao gồm luôn phiên bản Fortran-77, phần đặt tên (tên của các biến hoặc các chương trình con) hầu như chỉ có độ dài khoảng sáu ký tự (với các ký tự khởi đầu là các ký tự của bảng chữ cái). Trong Fortran-90/95, phần này có thể dài tới 31 ký tự và có thể bao gồm cả gạch chân. Fortran-2003 cho phép phần định danh tới 63 ký tự, Fortran không phân biệt chữ viết hoa và viết thường, nên chúng được xem là như nhau.

 

  1. Khung sường của lập trình Fortran

 

PROGRAM phần đặt tên  ! dòng này có thể để trống.

[Khai báo biến]

[các câu lệnh]

[STOP]

END

[SUBROUTINE và FUNCTION codes thường ở đây và không cần theo thứ tự.]

 

  • E- Dữ liệu

  1. Cấu trúc:

Fortran có cấu trúc scalars và cấu trúc arrays (thứ mà sử dụng DẤU NGOẶC ĐƠN trước và sau subscripts). Fortran-90/95/2003 đã giới thiệu cấu trúc records (i.e.,”classes,” còn được gọi là kiểu dẫn xuất)Pointers.

 

  1. Phân loại:

INTEGER, REAL, CHARACTER (LEN=…), LOGICAL, COMPLEX. Fortran-90/95/2003 đã đưa ra các phần mở rộng chuẩn xác của các loại cơ bản, do đó nó đã chiếm ưu thế hơn so với cách cũ (vẫn còn được phép sử dụng) DOUBLE PRECISION.

 

  1. Khai báo:

Trước khi thực thi bất kì câu lệnh nào của bất kì đoạn chương trình nào (i.e., chương trình chính hoặc phụ). Các biến (có thể) được khai báo. Không như lập trình C++ có thể sẽ không có bất cứ sự khai báo nào ở giữa chương trình được viết sau sự bắt đầu những đoạn code thực thi.

 

Fortran đã giữ lại cách gõ mặc định cho những biến không khai báo! Nếu trong phần đặt tên có chứa bất kỳ ký tự nào nằm giữa ký tự I và N (bào gồm luôn chúng), thì biến này thuộc vào loại INTEGER, phần còn lại đều thuộc loại REAL.

 

Bạn có thể “tắt” chức năng gõ mặc định này và bắt buộc mọi biến đều phải khai báo một cách rõ ràng bằng cách sử dụng

 

IMPLICIT NONE

Ngay trước lệnh khai báo biến và sau dòng bắt đầu PROGRAM (hay tương tự như vậy) của đoạn chương trình

–> Hiện nay cách này được khuyến khích luôn sử dụng IMPLICIT NONE để có thể phát hiện lỗi chính tả trong phần định danh!

 

Để có thể định danh biến một cách rõ ràng, bạn nên liệt kê chúng ngay phía sau tên loại (và bất cứ “thuộc tính” nào và không bắt buộc phải thêm vào hai dấu hai chấm) trong câu lệnh khai báo, phân biệt giữa các tên biến với nhau bởi dấu phẩy (tương tự như C/C++ syntax). E.g.,

 

 INTEGER I, J, K

 REAL :: X, Y, Z

 CHARACTER (LEN=10) :: NAME1, NAME2

 

Một cách cũ hơn để khai báo các ký tự của biến như sau”

 

CHARACTER*10 SURNAM

 

Để có thể khai báo một array, bạn có thể chỉ ra giá trị tối đa của subscript bên trong dấu ngoặc đơn (giả định như giá trị thấp là 1) phía sau phần định danh. Hoặc, bạn có thể thêm thuộc tính DIMENSION phía sau dấu phẩy và tên loại phía trước hai dấu hai chấm (đối với Fortran-90/95/2003). Bạn có thể chỉ định giá trị khởi đầu cho các subscript bằng các gõ giá trị thấp nhất và giá trị cao nhất chung với nhau, phân cách với nhau bằng dấu phẩy. E.g.,

 

 REAL A(50), B(-10:10)

 INTEGER, DIMENSION(10) :: IDNUMBERS

 INTEGER, DIMENSION(20:40) :: ROW_NUMBERS

 

Fortran-90/95/2003 cho phép một array chỉ định như là “ALLOCATABLE”, chỉ định số lượng và kích thước bằng cách sử dụng dấu hai chấm rồi sau đó phân bổ chúng bằng lệnh ALLOCATE trong chương trình. Bạn có thể sau đó sử dụng lệnh DEALLOCATE array nếu chúng không cần thiết nữa.

 

  1. Khởi tạo, khai báo hằng số:

Bạn có thể tạo một biến khi khai báo chúng. E.g.,

 

 REAL ::  A = 1.0

 INTEGER :: I = 2, J = 3

 

Hoặc, bạn có thể sử dung lệnh DATA cũ để khởi tạo biến và khai báo chúng rõ ràng hoặc theo mặc định.

 

 DATA  A/2.7/, I,J/3,5/

 

Để định danh một cách rõ ràng một hằng số không thể thay đổi, Fortran-90/95/2003 sử dụng thuộc tính PARAMETER khi khai báo biến và gán giá trị cho chúng, thí dụ,

 

 REAL, PARAMETER :: PI = 3.1415926

 

  1. Lưu trữ/phạm vi quy định:

Trong những đoạn mã độc lập, tất cả các biến được khai báo (rõ ràng hoặc không rõ ràng) đều thuộc về các chương trình chính (hoặc chương trình con). Không giống như các biến được khai báo trong chương trình chính trong Pascal, hoặc các biến được khai báo ngoài những tính năng của lập trình C/C++, trong Fortran không có biến toàn cục (trừ phi bạn sử dụng chương trình con nội vùng hoặc modules). Các thông tin được truyền tải đến các chương trình con độc lập thông qua parameter hoặc modules (hoặc thông qua lệnh COMMON cũ) .

 

  1. Mảng lưu trữ:

Các mảng đa chiều được lưu trữ theo trật tự “chuyên về Cột”. Nói cách khác, nếu chúng ta liệt kê những yếu tố của mảng theo trật tự mà chúng được lưu trữ, những subscript đầu tiên sẽ là phần được lưu trữ nhanh nhất.

CHÚ Ý: đây là điều trái ngược so với cách lưu trữ được sử dụng trong C/C++ và Pascal, thứ mà thường được gọi là trật tự “chuyên về Hàng”. Chương trình lưu trữ bị tác động khi lập trình viên cho phép ngôn ngữ chọn như mặc định, e.g., đối với input/output của mảng, hoặc khi liên kết một đoạn chương trình Fortran với các tính năng của đoạn chương trình C.

 

Ví dụ, giả sử chúng ta có mảng A khai báo là INTEGER A(3,3). Thì những thứ được lưu trữ sẽ theo thứ tự như sau:

 

A(1,1), A(2,1), A(3,1), A(1,2), A(2,2), A(3,2), A(1,3), A(2,3), A(3,3).

 

  1. Kiểu dẫn xuất:

Fortran-90/95/2003 sở hữu chức năng cho phép người dùng định nghĩa các loại biến “được ghi” (tương tự như C++ classes hoặc structs). Trong hệ thống thuật ngữ của Fortran-90/95/2003, đây được gọi là “kiểu dẫn xuất”. bạn sử dụng từ khóa TYPE ngay phía sau tên loại của người dùng tùy chọn và sau đó ở những dòng riêng biệt tiếp theo sẽ là những thành phần, ví dụ như sau:

 

TYPE INFOLINE

  CHARACTER (LEN = 30) :: NAME

  CHARACTER (LEN = 50) :: ADDRESS

  INTEGER :: ZIP

  INTEGER :: ACCNTNUM

END TYPE INFOLINE

 

Để khai báo các biến của loại mới, một lần nữa sử dụng từ khóa TYPE, và theo sau đó là tên của kiểu dẫn xuất được nằm trong dấu ngoặc đơn. Ví dụ:

 

TYPE (INFOLINE) :: ACCOUNT, LIST(100), TEMP

 

Nói chung, về nguyên tắt ghi biến thì tương tự như C++ và Pascal, ngoại trừ việc thay vì sử dụng dấu chấm, . , như là dấu ngăn cách, thì ở đây bạn phải dùng dấu phần trăm, %, ví dụ:

 

ACCOUNT%ZIP

LIST(1)%ACCNTNUM

 

  • F- Các hằng số:

  • Kiểu số học:

 

    Các số INTEGER được viết khi không có bất kỳ dấu chấm thập phân nào E.g., 5 hoặc -2.

 

    Các số REAL được viết khi có dấu chấm thập phân và (tùy) số mũ E.g., 3.1415926 hoặc 10.2E22

 

    Các số DOUBLE PRECISION real được viết khi có dấu chấm thập phân và số mũ với ký tự D phía trước nó E.g., 1.0D00.

 

Các hằng số Extended precision có thể được viết khi có đường gạch dưới và phần định danh có liên quan đến sự chính xác của nó E.g., 1.0_DP (giả sử DP là một giá trị thích hợp nào đó)

 

Các số COMPLEX được viết như là các cặp số REAL được năn cách nhau bởi dấu phẩy và nằm trong dấu ngoặc E.g., (5.2,6.721)

 

  1. Kiểu phi số học:

 

    Hằng số LOGICAL là . TRUE . and . FALSE . chúng phải được đặt giữa 2 dấu chấm.

 

    Chuỗi CHARACTER chứa những mệnh đề đơn (hoặc kép đối với Fortran-90/95/2003) e.g., ‘Hello’. Ở những phiên trước Fortran-90, chúng cho phép sử dụng “Hollerith” để miêu tả, cái mà ký tự H ở đầu kèm theo số ký tự của mệnh đề, e.g., 5Hhello. (Chú ý rằng kiểu mô tả Hollerith đã bị xem như “lỗi thời” và đã chính thức không còn trong Fortran 2003).

 

3.Kiểu Vectors :

Người ta có thể chỉ định nhiều giá trị không đổi cho các vector được lưu trữ như là mảng một chiều bằng cách đặt các giá trị vào giữa hai dấu kép. (/ và /). Ví dụ: nó có thể khai báo và khởi tạo một mảng bằng cách sử dụng vector của hằng số như là một “phương thức khởi tạo mảng” như sau:

 

INTEGER, DIMENSION(5) :: C = (/1, 3, 4, 0, 4 /)

 

  • G- Các lệnh điều hành:

  1. Kiểu toán học:

 

Lệnh vận hành là +,-,*,/ và ** (cho số mũ).

Ưu tiên: ** ưu tiên hơn * và / ưu tiên hơn + và -.

Ước lượng: từ trái qua phải ngoại trừ ** được lập lại.

Nên e.g., 2**3**5 thì tương đương với 2**(3**5).

Dấu ngoặc đơn được sử dụng như trong đại số để tăng quyền ưu tiên bình thường.

 

CHÚ Ý: Cũng như với C/C++ (khác với Pascal), / được dùng để chia cho cả integer và real và nó được thêm vào từ operands.

Nếu cả hai operand là integer, vậy phép chia INTEGER sẽ được thực hiện.

Nên ta có ví dụ:

5/2 thì gần bằng 2

2/5 thì gần bằng 0

5/2. thì gần bằng 2.5

2.0/5 thì gần bằng 0.4

 

  1. Kiểu Logical:

Hai hoặc ba ký tự của code được đặt giữa hai dấu chấm (cũng như đối với hằng số logic). Fortran-90/95/2003 cũng cho phép sử dụng ký hiệu này.

Mối liên hệ lệnh điều hành:

F77        F90/95/2003  

.EQ. ==

.LT. <

.LE. <=

.GT. >

.GE. >=

.NE. /=

 

Lệnh điều hành kết hợp:

 

Fortran     C++

        .AND.       &&

.OR.           ||

.NOT.   !

 

  1. Kiểu ký tự:

Hai dấu xoẹt (dấu chia), // (không có khoảng cách ở giữa) được sử dụng cho chuỗi “nối”  để gắn hai chuỗi ký tự thành một E.g.,

 

Nếu B là ký tự được khai báo như là một CHARACTER (LEN=7) và B = ‘John’ // ‘son’, vậy giá trị của B là Johnson

  • H- Cấu trúc lệnh điều khiển:

  1. Lệnh gán:

Mã gán được biểu hiện bởi = (không có dấu hai chấm nếu sử dụng Pascal). Ví dụ

 

A = 2 + 3

 

Chú ý: phía bên trái luôn là biến

Phía bên phải có thể là biến, chú thích hoặc tính năng.

 

Fortran-90/95/2003 cũng cho phép người dùng gán và thực hiện toán học cho các mảng biến. Ví dụ như, nếu A, B và C cùng nằm trên một mảng cùng chiều, lệnh gán (và lệnh toán học) được viết như là:

 

A = B + C

 

Là hợp lệ, và nó sẽ lấy các phần tử của mảng B và C và đặt kết quả vào A

 

Bạn có thể nhân mọi phần tử bên trong mảng cho một hằng số bằng cách tương tự ví dụ A = B * 3, hoạc dùng tính năng library để thực thi lệnh cho từng phần tử của mảng ví dụ A = SQRT ( B )

 

  1. Lệnh lặp:

Fortran-77 chỉ có một vòng lặp đếm, nhưng Fortran-90/95/2003 đã cho ra mắt vòng lặp có điều kiện và cũng như vòng lặp vô hạn. Vòng lặp đếm của Fortran thường được gọi là vòng lặp DO bởi vì từ khóa DO.

 

Cách cũ của Fortran-77 rõ ràng bao gồm câu lệnh số ở cuối của lệnh còng lặp DO. Câu lệnh cuối cùng thường là lệnh CONTINUE, câu lệnh này chẳng có tác dụng gì. Đây là ví dụ:

 

        DO 20 I = 1, 20

       …

  20    CONTINUE

 

Trong ví dụ này, biến vòng lặp của tôi bắt đầu từ giá trị 1 và kết thúc ở giá trị 20. Bất kỳ câu lệnh hợp lệ nào cũng có thể đưa ra ở cuối câu lệnh của vòng lặp

 

Theo cách của Fortran-90/95/2003 thì chúng sẽ bỏ qua các lệnh số thứ tự cà sữ dụng lệnh END DO như là câu lệnh cuối cùng của vòng lặp như trong ví dụ dưới đây cho thấy:

 

DO I = 1, 20

  …

END DO

 

Để sử dụng “stride” hoặc “step”, các bạn thêm dấu phẩy và con số trong dòng tiêu đều, ví du như sau:

 

DO I = 1, 23, 2

  …

END DO

 

Trong ví dụ này, tôi bắt đầu từ giá trị 1 và sẽ tăng lên 2 giá trị cho đến 23.( Để đếm “ngược”, bạn có thể sử dụng stride, ví dụ như, -1 ).


Như một vấn đề của cách làm này, ta không nên sử dụng lệnh vòng lặp DO cũ trong khi trình biên dịch chấp nhận lệnh vòng lặp DO của phiên bản Fortran-90/95/2003.

 

Trong phiên bản Fortran-66, không được phép thự hiện lệnh “stride” âm, và chấm dứt lệnh “test” được thực hiện vào cuối của vòng lặp. Như vậy, mỗi còng lặp DO được thực hiện ít nhất một lần, thậm chí nếu điều kiện dường như không phù hợp.

 

Với Fortran-77 và Fortran-90/95/2003, các test được thực hiện ở phần đầu của vòng lặp và việc cho giá trị phù hợp khởi đầu và dừng của vòng lặp cũng vậy, các phần bên trong của vòng lặp có thể không bao giờ được thực hiện.

 

Mặc dù Fortran-77 cung cấp khả năng của các biến và giá trị real như ranh giới của vòng lặp, điều này hiện đang trong kế hoạch sẽ bị liệt kê vào sự lỗi thời.

 

Sử dụng cấu trúc sau

 

DO

 …

END DO

 

Để bắt buộc thực hiện một vòng lặp vô hạn. mặc dù bản thân nó không hữu ích lắm, nhưng nó sẽ có ích khi bạn sử dụng kèm nó với mệnh đề EXIT.

 

Những lệnh EXIT được sử dụng với một một dòng IF (xem phần sau) và buộc chấm dứt vòng lặp. Chúng được minh họa như sau:

 

IF ( .NOT. (TOT <= 100) ) EXIT

 

Điều này sẽ kết thúc vòng lặp và tiếp tục chương trình với các lệnh sau khi END DO.

 

Chúng tôi có thể sử dụng CYCLE theo cách tương tự để bỏ qua phần còn lại của câu lệnh trong vòng lặp nhưng vẫn tiếp tục quá trình vòng lặp đó.

 

Fortran-90/95/2003 cũng bao gồm các vòng lặp DO WHILE ví dụ như sau:

 

DO WHILE (điều kiện)

  …

END DO

 

Miễn là điều kiện là đúng, vòng lặp sẽ tiếp tục hoạt động, nhưng khi điều kiện sai, sẽ thoát khỏi vòng lặp.

 

  1. Lựa chọn đơn giản (Lệnh IF):

Cấu trúc IF (“block IF”) thực hiện theo cùng một cách trong Fortran cũng như trong C ++, nhưng trong Fortran, bạn sử dụng một ENDIF để kết thúc các lệnh và từ khóa THEN theo sau điều kiện. Không cần dấu ngoặc để phân chia hoặc nhóm các lệnh với nhau, một trong hai. Ví dụ như

 

IF (A < B) THEN

  …

ELSE

  …

END IF

 

CHÚ Ý lệnh kết thúc END IF có thể được viết như một từ hoặc hai trên hầu hết các hệ thống. Chú ý rằng cũng IF … THEN, ELSE, ENDIF và câu lệnh của chúng phải nằm ở các dòng riêng biệt.

 

Các mệnh đề ELSE có thể được bỏ qua, ví dụ:

 

IF (A == B) THEN

  …

END IF

 

Bạn có thể viết một vài mệnh đề trong một ELSE IF nếu sử dụng hình thức sau đây trong đó một lệnh ELSE IF được đặt trên một dòng duy nhất

 

IF (A >= B) THEN

  …

ELSE IF (A > C) THEN

  …

ELSE

  …

END IF

 

Ở vị trí của THEN, người ta có thể đặt một lệnh đơn giản để gôm lệnh IF để một dòng. Ví dụ:

 

IF (A <= 0 ) A = -A

 

Điều này có thể được sử dụng trong Fortran-90/95/2003 để THOÁT ra khỏi một vòng lặp vô hạn (như ví dụ trên đã chứng minh).

Các phiên bản trình Fortran cũ bao gồm một “arithmetic IF” và một “(two-value) logical IF.” Mặc dù vẫn còn được hỗ trợ, nhưng chúng không được khuyến khích sử dụng, vì chúng được hoạt động bởi lệnh ngầm “GO TO”, câu lệnh không được khuyến khích sử dụng mạnh trong cách lập trình hiện đại.

 

  1. 4. Đa lựa chọn (Lệnh SELECT CASE)

Fortran-90/95/2003 bao gồm một lệnh mới tương ứng với câu lệnh switch của C ++ (hoặc của Pascal). Mỗi lựa chọn là một lựa chọn khác nhau (như trong Pascal) và do đó, lệnh break là không cần thiết như trong C ++. Ví dụ:

 

SELECT CASE (IVAR)

  CASE (1)

     CALL SUB1

  CASE (2:4)

     CALL SUB2

  CASE DEFAULT

     CALL SUB3

END SELECT

 

LƯU Ý:

(1) IVAR trong ngoặc sau SELECT CASE là biến mà giá trị sẽ được thử nghiệm với các tùy chọn được liệt kê trong các lựa chọn thay thế;

(2) sự lựa chọn thứ hai cho thấy làm thế nào để liệt kê một loạt các giá trị liên tục;

(3) mỗi tùy chọn là một sự lựa chọn loại trừ lẫn nhau (không giống như C ++).

 

  1. Lệnh END:

Mỗi đoạn chương trình (chương trình con) phải bao gồm một lệnh END như lệnh cuối cùng của nó. Điều này cho thấy sự kết thúc của code cho đoạn chương trình đó. Fortran-90/95/2003 cho phép bổ sung tuỳ chọn của các loại lệnh (ví dụ, PROGRAM, SUBPROGRAM, FUCTION, hoặc MODULE) và tên của lệnh (ví dụ như, END PROGRAM TEST).

 

  1. Lệnh chấm dứt chương trình:

STOP và RETURN là các câu lệnh báo hiệu kết thúc LOGIC (chứ không phải là kết thúc thường) của đoạn chương trình. Đoạn chương trình có thể có nhiều hơn một lệnh STOP hoặc RETURN nếu có nhiều hơn một điểm “chấm dứt” của mã.

STOP là lệnh thực thi cuối cùng trong chương trình chính và sẽ dừng chương trình (tương tự như exit call trong C / C ++).

 

RETURN là lệnh thực thi cuối cùng trong chương trình con và sẽ làm cho các chương trình con để trở về điểm mà chúng được khởi tạo.

 

Thông thường, một trong hai lệnh này, theo sự hiễn nhiên, được viết ngay trước lệnh END, là không cần thiết (tùy thuộc vào dòng logic của chương trình).

 

Fortran-90/95/2003 cho phép bỏ qua lệnh STOP hoặc RETURN khi nó đặt ngay trước END.

 

Một chương trình con cũng có thể bao gồm một lệnh STOP nếu kết mong muốn là làm chấm dứt ngay lập tức các chương trình mà không cần trở về bất kỳ điểm gọi.

 

  • I- I/O – nhập/xuất Input/Output

Trong Fortran chuẩn, lệnh Input và Output có hai phần:

 

  • lệnh hành động có thể thực thi (READ hoặc WRITE) với một danh sách biến (“CÁI GÌ” để làm gì);
  • lệnh không thể thực thi FORMAT quy định cụ thể các biến trong các lệnh liên quan được bố trí trên các dòng input/output NHƯ THẾ NÀO.

 

  1. Báo cáo FORMAT:

Những lệnh FORMAT bắt đầu với một số lệnh, bao gồm các từ khóa FORMAT và được theo sau bởi các cặp dấu ngoặc đơn có chứa một hoặc nhiều mô tả. Ví dụ:

 

   102     FORMAT(1X,I5,F10.3)

 

  • Những lệnh FORMAT mô tả, theo từng cột, sự hiện diện (ví dụ, “format”) của các dòng input hoặc output. Ngoài ra, chỉ có đầu output, nó cũng có thể chứa thông tin dành cho máy in (ví dụ, một ký tự trong “carriage control”).
  • Mỗi biến được liệt kê trong lệnh READ hoặc WRITE (theo bình thường) cần tương ứng với một miền mô tả trong lệnh FORMAT. (Quy định được tuân thủ nếu quá ít hoặc quá nhiều miền mô tả tồn tại, ví dụ, nếu có quá ít các mô tả, sự mô tả miền được sử dụng lại ở một dòng mới.)
  • Mỗi miền mô tả có thể chứa 3 phần: một số mutliplier tùy chọn, một kiểu dạng chữ cái, chiều rộng của miền (với một số thập phân subwidth cho số thực).
  • Các loại phổ biến là:

 

In Biểu thị cho Integer:

n chỉ ra số lượng khỏang trống cần thiết.

Ew.d Số thực Real ở dạng Số mũ:

w tương ứng với tổng số khoảng trống cần thiết.

d tương ứng với số lượng các chữ số bên phải dấu thập phân.

mô tả E (cho phần output) cần một khoảng cho ký tự E, ba khoảng trống cho các số mũ và dấu của nó, ba khoảng trống tiếp theo cho dấu chấm thập phân, số không trước dấu chấm thập phân, và một dấu trừ nếu có. Vì vậy, nói chung (cho phần output), w phải lớn hơn hoặc bằng d + 7.

Fw.d Số thực Real dưới hình thức cố định:

w tương ứng với tổng số khoảng trống cần thiết.

d tương ứng với số lượng các chữ số bên phải dấu thập phân.

An Chữ và số (ký tự):

n chỉ ra số lượng khoảng trống cần thiết.

nX Các khoảng trống:

n chỉ ra số lượng khoảng trống cần thiết. Lưu ý rằng số lượng đi trước các ký tự.

 

  • Một ví dụ về một định dạng cố định là F10.3 đó sẽ cho thấy tổng số 10 không gian được phân bổ cho một biến real, với 3 chữ số bên phải dấu thập phân (chúng có khoảng trống riêng của chúng).
  • Các số mutliplier tùy chọn chỉ ra một sự lặp lại của một miền mô tả. Nhóm các mô tả cũng có thể được đặt trong dấu ngoặc với mutliplier khác. Vì vậy, ta có ví dụ,

       12 FORMAT (3 (2I3, F3.1))

Tương đương với

       12 FORMAT (I3, I3, F3.1, I3, I3, F3.1, I3, I3, F3.1)

  • Chuỗi ký tự được đặt trong dấu ngoặc đơn. Fortran-90/95/2003 cũng cho phép sử dụng dấu ngoặc kép.
  • Mỗi câu lệnh output FORMAT (theo bình thường) tương ứng với output được viết trên dòng mới (trừ ký tự chỉ định carriage control khác). Để bao gồm các dòng mới thêm trong một tuyên bố FORMAT, một bao gồm một dấu gạch chéo, /.
  • Câu lệnh FORMAT có thể được đặt (một cách thủ công) bất cứ nơi nào trong chương trình. Nói chung có hai cách:
  • Ngay sau khi lệnh READ / WRITE tương ứng;
  • Tất cả ở đầu hoặc cuối của đoạn mã.
  • Lưu ý rằng một hoặc nhiều READ/WRITE có thể sử dụng vhung với câu lệnh FORMAT.

 

  1. Lệnh READ:

Các lệnh READ bao gồm các từ khóa READ, theo sau là một cặp các dấu ngoặc đơn có chứa những thông tin cần thiết, sau đó là một danh sách các biến (cách nhau bởi dấu phẩy). Vì vậy, nói chung, chúng ta có

 

READ(idevice,iformat) var_list

 

  • idevice là một số nguyên “thiết bị” mà trước đây đã được yêu cầu để phân biệt giữa các output khác nhau (ví dụ, terminal, băng đĩa, đầu đọc thẻ, file đĩa) trên máy một người dùng. Thông thường, bàn phím tương ứng với số lượng 5.
  • iformat là một số nguyên đề cập đến câu lệnh FORMAT tương ứng trong đó mô tả dòng input được sắp xếp như thế nào.

LƯU Ý: bạn có thể thay một dấu hoa thị, *, cho số FORMAT, đới với “FORMAT-free” I/O. Trong trường hợp này, trình biên dịch sẽ chọn FORMAT thích hợp nhất tương ứng với các loại của biến được liệt kê (cho OUTPUT) và sẽ cho rằng số đó nằm ở cuối khoảng trống (trên INPUT).

  • Các var_list là danh sách các biến, cách nhau bởi dấu phẩy. Các giá trị được đọc SANG các biến này, cho nên giá trị trước đó sẽ thay đổi.
  • Mảng có thể được liệt kê mà không cần bất kỳ subscript nào. Trong trường hợp này, toàn bộ mảng được giả định và trật tự các dữ liệu được lưu trữ đươc sắp xếp theo kiểu mặc định FORTRAN “column-major”.
  • Một “lệnh ngầm vòng lặp DO ” cũng có thể được sử dụng với các mảng bằng một trong hai lệnh READ hoặc WRITE, ví dụ

 

READ(5,*) (A(I),I=2,20,2), B, C

 

  • Người ta có thể loại bỏ các lệnh FORMAT riêng biệt bằng cách dùng dấu ngoặc kép trong phần ngoặc của câu lệnh FORMAT nơi số lệnh FORMAT thường sẽ được viết trong lệnh READ, ví dụ

READ(5,”(I2,F10.3)”) I, X

Kết quả cho ra một lệnh rất giống lệnh format đối với những gì diễn ra với I/O của lập trình C mà trong đó sử dụng một tuyên bố scanf, mô tả và các biến xảy ra trên một dòng của mô tả đó được nằm trong dấu ngoặc kép.

 

  • Bạn cũng có thể kiểm tra xem có phải bạn đang ở “end-of-file” trong lệnh READ-in bằng cách “đánh số thứ tự” phần thứ ba bên trong các dấu ngoặc đơn sau lệnh READ.Từ khóa là END và bạn gắn số lệnh (sau dấu =) để chỉ ra câu lệnh tiếp theo được thực hiện nếu đã gặp phải một “end-of-file”. Điều này có thể được sử dụng để “nhảy” ra khỏi một trong vòng lặp read-in để đến lệnh CONTINUE theo sau vòng lặp đó. Ví dụ

 

DO

         READ(20,100,END=30) I

      END DO

          30   CONTINUE

 

  • Đối với số input, khoảng trống có thể được giải thích theo một trong hai cách: hoặc là zero hoặc là NULL (tức là, bỏ qua). Khoảng trống zero là mặc định trong các phiên bản cũ của Fortran và với một số trình biên dịch Fortran-90 (ví dụ, Dec). khoảng trống null là mặc định trên Fortran-90 và các trình biên dịch khác (ví dụ, HP Unix). Để bắt buộc cách hiểu cách này hay cách khác, thêm vào BZ (cho Blanks là Zero) hoặc BN (cho Blanks là Null) trước khi mô tả trường số đầu tiên trong câu lệnh FORMAT.

 

  1. Lệnh WRITE:

Các lệnh WRITE bao gồm các từ khóa WRITE, theo sau là các cặp dấu ngoặc đơn chứa thông tin cần thiết, theo sau là danh sách các biến (cách nhau bằng dấu phẩy). Vì vậy, nói chung, chúng ta có

 

WRITE (iDevice, iformat) var_list

 

  • idevice là một số nguyên “thiết bị” số như với các lệnh READ. Thông thường, màn hình tương ứng với số 6.
  • iformat là một số nguyên đề cập đến câu lệnh FORMAT tương ứng. Bạn có thể dùng dấu sao cho “FORMAT-free” I/O. Một cũng có thể bao gồm các mô tả lĩnh vực trong dấu ngoặc kép để tránh một tuyên bố FORMAT riêng biệt.
  • Lệnh FORMAT kết hợp với lệnh WRITE phải bao gồm một đặc điểm kỹ thuật carriage control. Nếu không quy định một cách rõ ràng, các ký tự carriage control sẽ được giả định là một phần của trường mô tả đầu tiên.

 

  1. Tập tin I/O:

Tại SCU, trong Math/CS thuộc Linux Server math, bất kỳ số nào khác lớn hơn 5, 6, hoặc 7 có thể được sử dụng như số của thiết bị để liên kết input/output với các tập tin dữ liệu trong thư mục của người dùng. Số 20 sẽ được liên kết với các tập tin dữ liệu ftn20 và số khác sẽ thay đổi hai chữ số cuối cùng trong tên tập tin.

 

Fortran cũng bao gồm các lệnh cụ thể để MỞ và ĐÓNG các tập tin dữ liệu theo tên và kết hợp chúng với số thiết bị cụ thể.

 

  1. Carriage Control:

Trên DẠNG OUTPUT, ký tự đầu tiên mà SẼ được in không được in, mà bị máy in (và trên màn hình ở một số hệ thống)”ngốn” và được giải thích để xác định phần còn lại của các dòng được in như thế nào. Tính năng này đã bị loại bỏ ở Fortran 2003.

 

Để dễ hiểu, dễ nhất là hiểu dòng output bắt đầu bằng cột 0 hoặc cột “cc” (carriage control) và các cột THẤY ĐƯỢC đầu tiên là cột tiếp theo, tức là cột 1. Dù xuất hiện trong cột 0 không được in nhưng được hiểu như là một lệnh in.

 

Khoảng trống còn lại của dòng được in trên cùng một dòng

1 Một “top-of-form” (page eject) được thực hiện trước khi các thông tin còn lại được in (bỏ qua cột 0 trên đỉnh của trang tiếp theo).

0 double space“, tức là, một dòng được bỏ qua trước phần còn lại của dòng được in (bỏ qua cột 0 trên dòng tiếp theo).

+ Các dòng trước đó là overstruck (double space).

 

Để tránh những điều không mong muốn xảy ra trên phần output, trên thực tế phổ biến nhất là bắt đầu lệnh output FORMAT với một 1X hoặc ‘ ‘ như miền mô tả đầu tiên.

 

LƯU Ý: Hầu hết các ký tự khác đều bị bỏ qua (tức là, được hiểu như là một khoảng trống), mặc dù một vài hệ thống xử lý cho phép các khả năng khác

 

Lưu ý rằng Unix cung cấp các lệnh hệ thống asa để chuyển đổi các tập tin carriage control của Fortran sang các định dạng khác. Xem các tài liệu trên mạng để biết thêm thông tin.

 

  1. Sample Program:

        PROGRAM TEST2

IMPLICIT NONE

INTEGER NUM

REAL MILES, KILOS

WRITE(6,100)

        100 FORMAT(7X, ‘Miles’, 3X, ‘Kilometers’)

DO NUM = 5,60,5

  MILES = NUM

  KILOS = MILES*8.0/5.0

  WRITE(6,'(2F10.1)’) MILES, KILOS

END DO

STOP

END

 

  • J. Các chương trình con:

  • chức năng Library:

Có rất nhiều chức năng thư viện có sẵn mà có thể được áp dụng trong bất kỳ chương trình nào mà không cần bất kỳ câu lệnh sơ bộ “bao gồm-like” như trong C/C ++.

  • Math: ví dụ, SQRT, SIN, COS, LOG (tự nhiên), EXP, ABS. Fortran-90/95/2003 cho phép tên “chung chung” thế nên các chức năng đáp ứng kiểu dữ liệu output của nó tương ứng với các kiểu dữ liệu của biến input. Xem tài liệu tham khảo để có danh sách toàn diện hơn.
  • Type Conversion: ví dụ, CMPLX (A, B) – chuyển đổi hai giá trị REAL để cho ra một số COMPLEX, FLOAT (I) – chuyển đổi một giá trị INTEGER đến một giá trị REAL (mặc dù điều này cũng được thực hiện tự động thông qua lệnh gán).
  • Character: ví dụ, LEN (C) – cho độ dài của biến ký tự C, INDEX (C1, C2) – tìm vị trí bắt đầu của C2 trong C1, LGE (C1, C2) – “độ dài ký tự lớn hơn hoặc bằng “- trở về TRUE nếu C1 theo sau C2 trong thứ tự chữ cái.
  • Array/Matrix: (Những điều này đã được giới thiệu trong Fortran-90/95/2003). Một số các chức năng mới trả mảng như giá trị output của chúng thứ mà có thể được lưu trữ trong một mảng có kích thước phù hợp thông qua các biểu tượng gán đơn giản =. Vài ví dụ:
  • MATMUL (A, B): Cho cả A và B mảng hai chiều có kích thước phù hợp, MATMUL sẽ cho ra các tích số ma trận của A và B. B cũng có thể là một mảng một chiều (kết quả thu được từ tích số ma trận vector). (Trả về một mảng có chiều không gian thích hợp.)
  • DOT_PRODUCT (A, B): Cho cả A và B mảng một chiều cùng kích thước, DOT_PRODUCT sẽ cho ra kết quả vô hướng (“dot”) của A và B. (Trả về một scalar.)
  • TRANSPOSE (A): Nếu A là một mảng hai chiều, TRANSPOSE (A) sẽ trả về đảo vị của A. (Trả về một mảng của chiều không gian thích hợp.)
  • MAXLOC (A), MINLOC (A): Trả về vị trí của phần tử tối đa (hoặc tối thiểu) trong mảng A (như là vector của chiều dài thích hợp nếu A là chiều không gian cao cấp hơn).
  • MAXVAL (A), MINVAL (A): Trả về giá trị của phần tử tối đa (hoặc tối thiểu) trong mảng A (là một vô hướng của loại thích hợp).
  • SUM (A), PRODUCT (A): Trả về giá trị (hoặc kết quả) của tất cả các yếu tố trong mảng A (là một vô hướng của loại thích hợp). (A tham số thứ hai có thể chỉ định một chiều không gian, nếu muốn.)
  • RESHAPE (SOURCE, SHAPE): Đưa các giá trị của mảng nguồn (theo thứ tự column-major) và lưu trữ chúng theo hình dạng được chỉ định (được đưa ra như là một vector). (Trả về một mảng của không gian được xác định bởi các vector SHAPE.)

 

  1. Chức năng User-Defined:

Khi bạn viết một đoạn chương trình riêng biệt, đặt trong tập tin chương trình sau chương trình chính. Điều này làm cho chức năng, trong một nghĩa nào đó, trể nên “công khai” và thể được gọi bởi bất kỳ đoạn chương trình nào. Ngoài ra, người ta có thể bao gồm một chức năng “nội vùng” trong một chương trình chính ngay trước lệnh END nếu chèn lệnh CONTAINS ngay trước mã của chương trình con.

 

Dòng đầu tiên của một chức năng chỉ ra kiểu dữ liệu giá trị trả về của hàm, tiếp theo là từ khóa FUNCTION, kế đến là tên chức năng, rồi tới danh sách các tham số trong dấu ngoặc đơn. Ví dụ như

 

REAL FUNCTION ROOT(A,B,C)

 

  • Các loại chỉ là phụ. Nếu bỏ qua, cách gõ các biến mặc định được giả định dựa trên tên của chức năng.
  • Chỉ có tên các chức năng được đặt trong danh sách các tham số. Chúng được khai báo, được gõ, và chiều không gian bên trong mã FUNCTION.
  • Mã này thường bao gồm một lệnh RETURN ở kết thúc logic và phải có một lệnh END vào kết thúc vật lý.
  • Tên của CHỨC NĂNG (ví dụ, ROOT ở trên) là một biến của đoạn chương trình và phải được gán một giá trị trước lệnh RETURN. Biến này truyền tải được sự giá trị “return” trở lại vị trí của nó lúc vừa được gọi.
  • Trong đoạn gọi biến, tên chức phải đượcgõ chính xác (trừ khi sử dụng gõ mặc định) bằng cách bao gồm tên cua chức năng trong một lệnh khai báo kiểu như thể nó là một biến khác. Đối với các ví dụ nêu trên, trong đoạn gọi biến, ta có thể có:

 

           REAL :: ROOT, A, B, C

 

  • Fortran-90/95/2003 đã giới thiệu lệnh recursion cho chức năng User-Defined. Người ta phải chỉ định một cách rõ ràng một chức như là recursion bằng cách thêm các từ khoá FUNCTION trước các recursion. Ngoài ra, một biến “RESULT” riêng biệt cụ thể thông qua đó giá trị trả lại được chuyển tải. Biến này được đưa ra một loại trong mã. Ví dụ như,

 

         RECURSIVE FUNCTION FIBONACCI (N) RESULT (FIB_RESULT)

 

  1. Chương trình con:

Như với chức năng User-Defined, bạn có thể viết một chương trình con (tương ứng với một tính năng void trong C / C ++) là một đoạn chương trình riêng biệt hoặc được chứa như một routine nội vùng trong đoạn chương trình gọi.

 

Dòng đầu tiên của một chương trình con được bắt đầu với từ khóa SUBROUTINE, theo sau là tên chương trình con, tiếp theo là danh sách tham số trong ngoặc đơn. Ví dụ như,

 

            SUBROUTINE ROOTS (A, B, C, X1, X2)

 

  • Như với các FUNCTION, chỉ tên biến được đặt trong danh sách tham số. Chúng được khai báo, gõ, và chiều không gian bên trong code SUBROUTINE.
  • Như với các FUNCTION, các mã này thường bao gồm một lệnh RETURN cuối chuỗi lệnh logic và phải bao gồm một lệnh vật lý END ở cuối đoạn mã.
  • Một SUBROUTINE được đẫn từ một chương trình gọi bằng lệnh CALL bao gồm từ khóa CALL trước tên chương trình con và các thông số của nó. Ví dụ như,

 

             CALL ROOTS (A, B, C, PROOT, NROOT)

 

  1. Ghi chú:
  1. GHI NHỚ: Trong chức năng user-defined bên ngoài (hoặc “toàn cục”), tất cả các biến đều thuộc nội vùng. Thông tin phải được chuyển tải thông qua tham số/thông số hoặc thông qua các MODULES hoặc lệnh COMMON.
  2. Mã chương trình con đi sau mã chương trình chính hoặc trước khi kết thúc chương trình chính (nếu nội vùng), sau lệnh CONTAINS.
  3. HÃY NHỚ: lệnh FUNCTION sẽ trả lại một giá trị. Vì vậy nó phải được sử dụng (ví dụ, được gán cho một biến). Cf. theo cách các chức năng học thư viện toán sử dụng (ví dụ, sqrt, sin).
  4. Tất cả các thông số Fortran có thể thay đổi giá trị. Fortran không tương đương với giá trị thông số trong C / C ++. (Mảng được luôn chạy vượt qua “address/reference.” Tùy thuộc vào trình biên dịch,vô hướng đươc chạy vượt qua một trong hai “address/reference” hoặc “value-result.” nhiều lần ở nơi nào đó.)
  5. Thông số chương trình con Fortran có thể là tên của một fuction. Vì vậy, ví dụ, ta có thể viết một chương trình con để tính năng nó gần đúng với một fuction tùy ý, và đưa fuction này vào chương trình con như là một trong những thông số.

 

  1. 5. Chương trình mẫu:

       PROGRAM FINDROOT

REAL :: A,B,C,X1,X2

READ(5,*) A,B,C

CALL ROOTS(A,B,C,X1,X2)

WRITE(6,10) A,B,C

10 FORMAT(1X, ‘The roots of’, F10.2,’x**2 + ‘, &

         F10.2,’x + ‘,F10.2,’ are ‘)

       WRITE(6,11) X1,X2

11 FORMAT(1X,F10.5,’ AND ‘,F10.5)

STOP

END

!

SUBROUTINE ROOTS(A,B,C,XP,XN)

REAL :: A,B,C,XP,XN,RAD

RAD = SQRT(B**2 – 4.0*A*C)

XP = (-B+RAD)/(2.0*A)

XN = (-B-RAD)/(2.0*A)

RETURN

END

 

6.Các Module:

Fortran-90/95/2003 đã giới thiệu một đoạn chương trình mới được gọi là MODULE. Nó có thể chứa các loại như định nghĩa, khai báo biến, và thậm chí cả đoạn chương trình chuyên ngành. Nó hữu ích nhất khi một vài phân đoạn chương trình con sử dụng dữ liệu User-defined cùng loại, hoặc một loạt các biến hoặc một bộ các chức năng liên quan đến một loại dữ liệu cụ thể. Kể từ khi các yếu tố trong một module có thể được chỉ định là CÔNG KHAI hay RIÊNG TƯ, một module có thể được sử dụng cho lớp thực hành lập trình hướng đối tượng với cách tương tự như C ++.

 

  • Mỗi một module đều có tên riêng của mình.
  • Mỗi phân đoạn chương trình sử dụng làm của một module gọi các module với một lệnh USE trong đó bao gồm tên của module.
  • Các module được đặt trước khi lệnh đầu tiên gọi nó trong tập tin mã nguồn.

 

Một ví dụ đơn giản của một module có chứa dữ liệu như sau:

 

MODULE SAMPLE1

  INTEGER, DIMENSION (10) :: K

     END MODULE

  !

     PROGRAM TEST8

        USE SAMPLE1

     INTEGER I

     CALL SUB1

     DO I = 1,10

WRITE(6,*) K(I)

     END DO

     END

  !

     SUBROUTINE SUB1

        USE SAMPLE1

     INTEGER I

     DO I = 1, 10

  K(I) = 21-2*I

     END DO

     RETURN

     END

 

Sau đây là một ví dụ về định nghĩa module cho một chùm các dữ liệu được chỉ định là RIÊNG TƯ và các chức năng bên trong chùm dữ liệu đó được mã hóa như là một đoạn chương trình module

 

       MODULE STACK_MOD

         TYPE STACK

            PRIVATE

             INTEGER :: STACKELEMENT(100)

             INTEGER :: TOP

          END TYPE

       CONTAINS

         SUBROUTINE INIT(S)

         TYPE(STACK) :: S

         S%TOP = 0

         END SUBROUTINE

         !

         SUBROUTINE PUSH(S,ITEM)

         TYPE(STACK) :: S

         INTEGER :: ITEM

         IF (S%TOP < 100) THEN

            S%TOP=S%TOP+1

            S%STACKELEMENT(S%TOP) = ITEM

         ELSE

            WRITE(*,*) “STACK OVERFLOW”

            STOP

         ENDIF

         END SUBROUTINE

         !

         INTEGER FUNCTION POP(S)

         TYPE(STACK) :: S

         IF (S%TOP > 0) THEN

           POP = S%STACKELEMENT(S%TOP)

           S%TOP = S%TOP-1

         ELSE

           WRITE(*,*) “STACK UNDERFLOW”

           STOP

         ENDIF

         END FUNCTION

       END MODULE

 


  • K- Pointer

 

Biến pointer đã được giới thiệu trong Fortran-90/95/2003 và nó là tương tự, nhưng không giống với khái niệm về pointer trong các ngôn ngữ khác thực hiện pointer. Trong các ngôn ngữ lập trình khác, nhận dạng pointer thường chứa address (chứ không phải là một integer, real, character, hoặc loại giá trị khác). Ngược lại, một pointer trong Fortran-90/95/2003 là một alias, một cái tên thay thế, cho biến mà nó trỏ tới. Trong thực tế, điều này có nghĩa

 

  • rằng, kể từ Fortran-90/95/2003, các biến pointer không lưu trữ các address, nó mang giá trị giá trị giống như các biến mà nó trỏ tới;
  • rằng các biến pointer Fortran-90/95/2003 không cần bất kỳ loại “dereferencing” (ví dụ, C/C ++ * hoặc Pascal ^) để có được những giá trị kết hợp với các biến pointer.

 

Một sự khác biệt lớn trong cách các “pointer” có thể được sử dụng trong Fortran-90/95/2003 là nó cũng có thể được sử dụng để “chỉ” ra một phần của một cấu trúc dữ liệu lớn, ví dụ, chỉ ra một hàng hoặc cột của một mảng. Ngoài ra, chúng có riêng quyền được sử dụng các biến. Như vậy, khái niệm về một biến “pointer” trong Fortran-90/95/2003 linh hoạt hơn so với các biến tương tự trong các ngôn ngữ lập trình khác.

 

  1. Khai báo biến pointer đơn giản:

Để khai báo một biến pointer, một thêm từ khóa thuộc tính POINTER trong khai báo biến trước hai dấu hai chấm, như sau:

 

          REAL, POINTER :: Y

 

Bạn cũng cần phải xác định những biến số mà Y (hoặc bất kỳ pointer thích hợp khác) có thể trỏ, và điều này được thực hiện bằng cách thêm từ khóa thuộc tính TARGET trong phần khai báo biến của các biến như, như sau:

 

          REAL, TARGET :: X

 

  1. Sự gán biến con trỏ:

Fortran-90/95/2003 đã giới thiệu lệnh gán biến pointer được chỉ định bằng cách sử dụng hai biểu tượng đi với nhau theo cách này: =>

 

Nếu X và Y được khai báo như trong phần trước, và nếu một người khởi tạo lệnh gán con trỏ,

 

          Y => X

 

sau đó Y sẽ có hiệu lực, trở thành một alias cho X. Nói cách khác, các vị trí nhớ liên quan với X là bây giờ vị trí nhớ cũng liên quan với Y. Vì vậy, nếu giá trị của biến X, thì giá trị của Y và ngược lại , kể từ khi cả X và Y được xem một và cùng một vị trí nhớ.

 

  1. Sử dụng biến pointer cho các cấu trúc liên kết:

Người ta có thể sử dụng các biến pointer trong Fortran-90/95/2003 để tạo các node cho các cấu trúc liên kết tương tự như những gì được thực hiện trong các ngôn ngữ lập trình khác. Ví dụ, một node danh sách trong có thể được xem như là một kiểu dữ liệu mới “được suy ra” bằng cách sử dụng một biến pointer như sau:

 

     TYPE NODE

        INTEGER     :: INFO

       TYPE (NODE), POINTER :: NEXT

     END TYPE NODE

 

Sau khi xác định kiểu dữ liệu NODE mới này, bạn có thể khai báo các biến được trỏ tới phần tử kiểu dữ liệu này theo cách thông thường, ví dụ:

 

     TYPE (NODE), POINTER :: LISH, TEMP

 

Lệnh này sẽ khai báo LIST và TEMP như là một biến mà có thể được sử dụng như để trỏ đến các phần nguồn gốc bộ nhớ của loại NODE.

 

Lưu ý, tuy nhiên, sau khi khai báo, LIST và TEMP không chứa bất kỳ thông tin, cũng không “trỏ” đến bất kỳ node nào. Điều này là bởi vì đã không có các biến khai báo thuộc tính “target” cho pointer và không có sự liên hệ nào đã diễn ra!

 

Để cấp phát bộ nhớ cho một node, người ta có thể sử dụng các câu lệnh ALLOCATE thư viện, tương tự như chức năng NEW trong Pascal ++ hoặc chức năng NEW tron C khi được sử dụng với các biến pointer. Cau lệnh được sử dụng như sau:

 

     ALLOCATE (LIST)

 

Làm cho bộ nhớ được cấp phát cho một biến có nguồn gốc của các loại được khai báo trong lệnh LIST (ví dụ, trong trường hợp này, các loại trong NODE) ​​và sau đó LIST có thể được sử dụng để truy cập vào các lĩnh vực của node.

 

Một biến pointer có thể được thiết lập hoặc thiết lập lại “vô giá trị” bằng cách khởi tạo lệnh NULLIFY thư viện. (Điều này có tác dụng tương tự như sử nil trong Pascal hoặc NULL trong C ++ trong câu lệnh gán.) Trong Fortran-90/95/2003, lệnh này được sử dụng như trong ví dụ này:

 

     NULLIFY (LIST% NEXT)

 

Fortran-95 cũng cho phép LIST% NEXT => NULL ()

 

  • L- Các câu lệnh và chức năng khác

Có nhiều câu lệnh và cấu trúc khác trong Fortran, một số tương đối mới, những câu lệnh khác ít được sử dụng, hoặc chỉ sử dụng trong việc triển khai nhất định. Các lập trình viên nên tìm hiểu trong sách hoặc hướng dẫn sử dụng để biết thêm thông tin. Một số lệnh cũ, nhưng ít được sử dụng, của Fortran-90/95/2003bị cho là “lỗi thời”.

 

  • SỰ ĐẶC TẢ (CŨ): DIMENSION (nay được thành lập như là một loại thuộc tính để chỉ ra các mảng), EQUIVALENCE (phần nào đã bị lỗi thời bởi lệnh POINTER), IMPLICIT (phạm vi biến ban đầu) (kiểu gõ implicit được coi là kiểu gõ dở), PARAMETER (nay là thành lập như là một loại thuộc tính để chỉ ra các hằng số),
  • SỰ ĐẶC TẢ (CHUYÊN DỤNG): EXTERNAL (chỉ ra dấu hiệu tên của chương trình con sử dụng tính năng User-defiled thông qua như là một tham số để đến chương trình con), INTRINSIC (chỉ ra tên của một thư viện tiểu chương trình).
  • LỆNH ĐIỀU KHIỂN (CŨ): Các câu lệnh chức năng SAVE, PAUSE, GO TO, ENTRY.
  • LỆNH ĐIỀU KHIỂN (FORTRAN-90/95/2003): chức năng WHERE … ELSEWHERE … ENDWHERE như một lệnh IF có điều kiện liên quan đến một mảng. Các điều kiện được kiểm tra cho mỗi phần tử trong mảng, và các lệnh tương ứng được thực hiện tùy thuộc vào việc các điều kiện là TRUE hoặc FALSE. Nếu các lệnh khởi tạo một mảng, các hành động được thực hiện trên các phần tử mảng mà các subscript phải tương ứng với điều kiện hiện tại. FORALL (Fortran-95) có chức năng như một vòng lặp DO loop song song trong đó thứ tự các giá trị biến vòng lặp được xem là không được chỉ định, do đó, có thể được thực hiện song song trên bộ xử lý riêng biệt. vòng lặp DO có thể được đánh số thứ tự dưới dạng chuỗi ký tự, có thể được sử dụng với lệnh CYCLE hoặc EXIT vòng lặp.
  • I/O: PRINT, TYPE, OPEN, CLOSE, REWIND, mô tả lĩnh vực ĐỊNH DẠNG khác, ví dụ, G, T, $, H, tùy chọn bổ sung trong lệnh READ (ví dụ, ERR, END).
  • CHƯƠNG TRÌNH CON: (Fortran-90/95/2003) tham số có thể được chỉ định là OPTIONAL, và cũng đưa ra một thuộc tính INTENT của lệnh IN, OUT, hay INOUT. Tham số thực tế cũng có thể được đánh số thứ tự tương ứng với các tham số giả và trong bất kỳ thứ tự nào.
  • MẢNG: Người ta có thể chỉ định các phần của một mảng (tức là, hàng, cột, hoặc subblock).
  • GIAO DIỆN: (Fortran-90/95/2003) cấu trúc giao diện có thể được sử dụng trong Fortran-90/95/2003 bằng nhiều cách. (1) Nó có thể được sử dụng theo cách tương tự như dòng “prototype” cho các chức năng trong C/C ++. Giao diện được đặt trong phân đoạn chương trình gọi trước bất kỳ khai báo biến nào và lặp lại lệnh tiêu đề cho các chương trình, các khai báo các thông số, và lệnh cuối cùng của chương trình. Điều này là cần thiết khi một trong những thông số là một pointer hoặc một mảng có thể phân bổ hay một mảng có chiều hướng không xác định. (2) Nó cũng có thể được sử dụng để xác định hoặc vận hành quá tải hoặc các lệnh gán. (3) Nó cũng có thể được sử dụng để chỉ định tên chương trình con chung cho dữ liệu chương trình con cụ thể (ví dụ, khi chương trình con khác nhau về kiểu dữ liệu của các tham số của nó).

 

  • M- Phong cách của lập trình Fortran

  • Fortran đã có từ hai thập kỷ trước khi sự cải tiến quan tâm về cách lập trình và cấu trúc của các chương trình.
  • Như vậy, phiên bản đầu tiên có cấu trúc điều khiển tối thiểu và câu lệnh “tai tiếng” GOTO thứ mà tạo điều kiện thuận lợi cho các “spaghetti code”.
  • Việc đưa vào các phiên bản Fortran gần đây của lệnh END DO, lệnh WHILE DO, khối lệnh IF, và câu lệnh SELECT CASE đã loại bỏ nhiều xu hướng viết mã Fortran phi cấu trúc được tìm thấy trong cuốn sách trước đó.

 

Do thiếu các cấu trúc chạy chương trình trong các phiên bản cũ của trình Fortran, và việc sử dụng vô kỷ luật của lệnh GOTO, thật là khó khăn khi mã thường được viết bằng cách cũ này, nếu không phải không thể đọc, nên việc gỡ lỗi cũng thế. Ví dụ sau đây cho thấy phần tương đương với mã được viết bằng cách cũ (mà vẫn là mã Fortran trên pháp lý) và viết lại bằng cách sử dụng Fortran-90/95/2003 câu lệnh SELECT CASE và một khối lệnh IF.

 

Phân đoạn phi cấu trúc của Fortran (theo cách cũ trong FORTRAN 66)

 

IF(K.EQ.1) GO TO 212

IF(K.EQ.2) GO TO 18

GO TO 106

 212 X(1) = 5.

        Y(K) = K+2.5

  32 IF(K*J.LE.4) GO TO 184

  30 L4 = K*J-K+1

        Y(L4) = 1.0

        X(L4) = Y(L4)

 210 IF(K-J.GE.7) GO TO 265

        GO TO 184

  18 X(K) = 6.

        Y(K) = K-1.5

GO TO 32

 106    IF(K.NE.3) GO TO 10

       Y(K) = 0.0

        X(K) = Y(K)

GO TO 23

 265 IF(K.GE.J+7) GO TO 10

        X(K-J+1) = 0.0

Y(K-J+1) = 1.0

GO TO 10

 184 IF(K*J.LE.4) GO TO 23

 180 L = K*J-2*K

       Y(L) = 0.0

X(L) = Y(L)

  23 IF(K-J.GE.7) X(K-J+1) = 1.0

        IF(K*J.LE.4) GO TO 30

GO TO 265

  10 IF(K-J.GE.7) Y(K-J+1) = 0.0

 

Phân đoạn tương đương của Fortran có cấu trúc (theo cách mới của Fortran-90/95/2003)

 

SELECT CASE (K)

  CASE(1)

     X(1) = 5.0

     Y(K) = K+2.5

  CASE(2)

     X(K) = 6.

     Y(K) = K-1.5

  CASE(3)

     X(K) = 0.0

     Y(K) = 0.0

END SELECT

IF(K*J <= 4) THEN

     L4 = K*J-K+1

     X(L4) = 1.0

     Y(L4) = 1.0

  ELSE

     L = K*J-2*K

     X(L) = 0.0

     Y(L) = 0.0

END IF

IF(K-J >= 7) THEN

     X(K-J+1) = 1.0

     Y(K-J+1) = 0.0

  ELSE

     X(K-J+1) = 0.0

     Y(K-J+1) = 1.0

END IF

 

  •  N- Thực liệu học

Chương trình Fortran được biên dịch (không phải diễn giải). Thông thường, các phần của mã (ví dụ, các thư viện chương trình con) đều được biên dịch riêng rẽ và liên kết với nhau trước khi thực hiện.

 

Trong các phiên bản cũ của trình Fortran, biến được phân bổ là tĩnh. Còn Fortran-90/95/2003 cho phép phân bổ năng động của các pointer và mảng. Theo mặc định, tất cả các biến đều thuộc nội vùng.

 

Bởi vì sự phân bổ biến tĩnh trong các phiên bản cũ của trình Fortran, các đoạn mã gọi chương trình con đệ quy không tồn tại.

 

  •  O- Chú giải

  1. Khoảng năm 1985 người ta ước tính rằng có hơn 36,4 tỷ € mã Fortran tồn tại. Cho đến gần đây, tất cả đa số các gói phần mềm tốc hoạt lớn đều được viết bằng Fortran. Fortran-90/95/2003 có các tính năng được thiết kế để xử lý mảng trên các máy tính song song mà các ngôn ngữ lập trình khác không có.
  2. Các dòng máy tính Cray có trình biên dịch cho Fortran-77, Fortran-90, C, và một phiên bản của C ++.
  3. Tiếp tục phát triển “High Performance Fortran (HPF),” một siêu phiên bản của Fortran trang bị dành cho tiên tiến, xử lý song song. Mã viết bằng HPF thường có các lệnh bổ sung mà bắt đầu bằng! HPF, mà khi chạy bằng phiên bản chuẩn Fortran-90/95/2003 sẽ bị bỏ qua mặc dù nó được bắt đầu bằng tính hiệu của sự chú thích, dấu chấm than.
  4. Sự phát triển liên tục của Fortran được thúc đẩy bởi sự phát triển trong nghiên cứu trừu tượng và phân tích ngôn ngữ máy tính kể từ năm 1950.

 

Hình thức cú pháp ban đầu của Fortran dẫn đến lo ngại về tính đầy đủ của các đặc điểm kỹ thuật, xác định biểu thức hợp pháp, sự không rõ ràng của cấu hình.

 

Sự phát triển của lý thuyết trình biên dịch chỉ ra rằng các phiên bản trước đó của Fortran là thảm họa cho sự dịch mã và do đó việc cải thiện là điều mong muốn. Điều này chiếm một phần các tính năng mới trong phiên bản mới hơn của Fortran.

 

Fortran thường bị chỉ trích khoảng trống thảm họa vì tính năng khai báo “kiểu mặc định”. (Mặc dù điều “chỉ trích” này ngày nay được cho là sai.) Việc thủy thủ người Mỹ đầu tiên tên lửa thứ I, được phóng vào ngày 22 tháng 7 năm 1962 từ Cape Canaveral trong nhiệm vụ đầu tiên tới saoVenus, đã bị phá hủy với giá 16.83€ triệu vì nó lại chuyển hướng hướng tới các khu vực dân cư. Việc chỉ trích thường được đặt trên một sai lầm bởi một lập trình viên. Nó đã được phổ biến cho rằng, thay vì viết

 

        DO 3 I = 1,3! dấu phẩy giữa 1 và 3

 

một lập trình viên đã viết

 

        DO 3 I = 1.3! dấu chấm giữa 1 đến 3

 

Phát biểu đầu tiên là một lệnh ban đầu hợp pháp cho một vòng lặp đếm, nhưng tuyên bố thứ hai là một lệnh gán hợp pháp cho biến REAL DO3I  cho giá trị 1,30.

 

Bằng việc sử dụng lệnh END DO và Định dạng mã nguồn tự do, LỖI này bây giờ sẽ được phát hiện trong quá trình biên dịch.

________________________________________________________________________

 

Trang này được duy trì bởi Dennis C. Smolarski, SJ dsmolarski “tại” scu.edu

Cập nhật: ngày 28 tháng 9 năm 2005. Cập nhật nhỏ vào 31 tháng 3 năm 2011. cập nhật bổ sung, ngày 24 tháng 5 năm 2012; 18 tháng 9 năm 2012; 19 tháng 9 năm 2012; Ngày 25 tháng 9 năm 2012. Sữa chữa nơi FORTRAN được phát triển ban đầu: ngày 07 tháng 3 năm 2014.

Advertisements