Fortran - Hướng dẫn nhanh
Fortran, bắt nguồn từ Hệ thống dịch công thức, là một ngôn ngữ lập trình mệnh lệnh, có mục đích chung. Nó được sử dụng cho tính toán số và khoa học.
Fortran ban đầu được phát triển bởi IBM vào những năm 1950 cho các ứng dụng khoa học và kỹ thuật. Fortran đã thống trị lĩnh vực lập trình này trong một thời gian dài và trở nên rất phổ biến đối với tính toán hiệu suất cao, bởi vì.
Nó hỗ trợ -
- Phân tích số và tính toán khoa học
- Lập trình có cấu trúc
- Lập trình mảng
- Lập trình mô-đun
- Lập trình chung
- Tính toán hiệu suất cao trên siêu máy tính
- Lập trình hướng đối tượng
- Lập trình đồng thời
- Mức độ di động hợp lý giữa các hệ thống máy tính
Sự thật về Fortran
Fortran được tạo ra bởi một nhóm, dẫn đầu bởi John Backus tại IBM vào năm 1957.
Ban đầu tên được sử dụng để viết hoa, nhưng các tiêu chuẩn và triển khai hiện tại chỉ yêu cầu chữ cái đầu tiên là viết hoa.
Fortran là viết tắt của FORmula TRANslator.
Ban đầu được phát triển để tính toán khoa học, nó hỗ trợ rất hạn chế cho các chuỗi ký tự và các cấu trúc khác cần thiết cho lập trình mục đích chung.
Các phần mở rộng và phát triển sau này đã biến nó thành một ngôn ngữ lập trình cấp cao với tính di động tốt.
Phiên bản gốc, Fortran I, II và III được coi là lỗi thời.
Phiên bản cũ nhất vẫn đang được sử dụng là Fortran IV và Fortran 66.
Các phiên bản được sử dụng phổ biến nhất hiện nay là: Fortran 77, Fortran 90 và Fortran 95.
Fortran 77 đã thêm các chuỗi như một kiểu riêng biệt.
Fortran 90 đã thêm nhiều loại phân luồng và xử lý mảng trực tiếp.
Thiết lập Fortran trong Windows
G95 là trình biên dịch đa kiến trúc GNU Fortran, được sử dụng để thiết lập Fortran trong Windows. Phiên bản windows giả lập môi trường unix bằng MingW bên dưới windows. Trình cài đặt sẽ xử lý việc này và tự động thêm g95 vào biến PATH của windows.
Bạn có thể tải phiên bản ổn định của G95 từ đây
Cách sử dụng G95
Trong quá trình cài đặt, g95sẽ tự động được thêm vào biến PATH của bạn nếu bạn chọn tùy chọn “RECOMMENDED”. Điều này có nghĩa là bạn có thể chỉ cần mở một cửa sổ Command Prompt mới và nhập “g95” để hiển thị trình biên dịch. Tìm một số lệnh cơ bản bên dưới để giúp bạn bắt đầu.
Sr.No | Lệnh & Mô tả |
---|---|
1 | g95 –c hello.f90 Biên dịch hello.f90 thành một tệp đối tượng có tên hello.o |
2 | g95 hello.f90 Biên dịch hello.f90 và liên kết nó để tạo ra một a.out thực thi |
3 | g95 -c h1.f90 h2.f90 h3.f90 Biên dịch nhiều tệp nguồn. Nếu mọi việc suôn sẻ, các tệp đối tượng h1.o, h2.o và h3.o sẽ được tạo |
4 | g95 -o hello h1.f90 h2.f90 h3.f90 Biên dịch nhiều tệp nguồn và liên kết chúng với nhau thành một tệp thực thi có tên 'xin chào' |
Tùy chọn dòng lệnh cho G95
-c Compile only, do not run the linker.
-o Specify the name of the output file, either an object file or the executable.
Nhiều tệp nguồn và tệp đối tượng có thể được chỉ định cùng một lúc. Tệp Fortran được biểu thị bằng các tên kết thúc bằng ".f", ".F", ".for", ".FOR", ".f90", ".F90", ".f95", ".F95", ". f03 "và" .F03 ". Nhiều tệp nguồn có thể được chỉ định. Các tệp đối tượng cũng có thể được chỉ định và sẽ được liên kết để tạo thành một tệp thực thi.
Một chương trình Fortran được tạo ra từ một tập hợp các đơn vị chương trình như một chương trình chính, các mô-đun và các chương trình con hoặc thủ tục bên ngoài.
Mỗi chương trình chứa một chương trình chính và có thể có hoặc không chứa các đơn vị chương trình khác. Cú pháp của chương trình chính như sau:
program program_name
implicit none
! type declaration statements
! executable statements
end program program_name
Một chương trình đơn giản ở Fortran
Hãy viết một chương trình cộng hai số và in ra kết quả:
program addNumbers
! This simple program adds two numbers
implicit none
! Type declarations
real :: a, b, result
! Executable statements
a = 12.0
b = 15.0
result = a + b
print *, 'The total is ', result
end program addNumbers
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
The total is 27.0000000
Xin lưu ý rằng -
Tất cả các chương trình Fortran đều bắt đầu bằng từ khóa program và kết thúc bằng từ khóa end program, theo sau là tên của chương trình.
Các implicit nonecâu lệnh cho phép trình biên dịch kiểm tra xem tất cả các kiểu biến của bạn đã được khai báo đúng chưa. Bạn phải luôn sử dụngimplicit none khi bắt đầu mọi chương trình.
Nhận xét trong Fortran được bắt đầu bằng dấu chấm than (!), Vì tất cả các ký tự sau dấu chấm than (ngoại trừ trong một chuỗi ký tự) đều bị trình biên dịch bỏ qua.
Các print * lệnh hiển thị dữ liệu trên màn hình.
Thụt lề các dòng mã là một phương pháp hay để giữ cho một chương trình có thể đọc được.
Fortran cho phép cả chữ hoa và chữ thường. Fortran không phân biệt chữ hoa chữ thường, ngoại trừ các ký tự chuỗi.
Khái niệm cơ bản
Các basic character set của Fortran chứa -
- các chữ cái A ... Z và a ... z
- các chữ số 0 ... 9
- ký tự gạch dưới (_)
- các ký tự đặc biệt =: + blank - * / () [] ,. $ '! "% &; <>?
Tokensđược tạo bởi các ký tự trong bộ ký tự cơ bản. Mã thông báo có thể là một từ khóa, một số nhận dạng, một hằng số, một chuỗi ký tự hoặc một ký hiệu.
Các câu lệnh chương trình được làm bằng các mã thông báo.
Định danh
Mã định danh là tên được sử dụng để xác định một biến, thủ tục hoặc bất kỳ mục nào khác do người dùng xác định. Tên trong Fortran phải tuân theo các quy tắc sau:
Nó không được dài hơn 31 ký tự.
Nó phải bao gồm các ký tự chữ và số (tất cả các chữ cái trong bảng chữ cái và các chữ số từ 0 đến 9) và dấu gạch dưới (_).
Ký tự đầu tiên của tên phải là một chữ cái.
Tên không phân biệt chữ hoa chữ thường
Từ khóa
Từ khóa là những từ đặc biệt, dành riêng cho ngôn ngữ. Những từ dành riêng này không thể được sử dụng làm định danh hoặc tên.
Bảng sau đây liệt kê các từ khóa Fortran -
Các từ khóa không phải I / O | ||||
---|---|---|---|---|
phân bổ | chỉ định | chỉ định | sự phân công | khối dữ liệu |
gọi | trường hợp | tính cách | chung | phức tạp |
chứa đựng | tiếp tục | đi xe đạp | dữ liệu | thỏa thuận |
mặc định | làm | chính xác gấp đôi | khác | khác nếu |
nơi khác | dữ liệu khối kết thúc | kết thúc làm | chức năng kết thúc | kết thúc nếu |
giao diện kết thúc | mô-đun kết thúc | kết thúc chương trình | kết thúc lựa chọn | kết thúc chương trình con |
loại kết thúc | kết thúc ở đâu | nhập cảnh | tương đương | lối ra |
bên ngoài | chức năng | đi đến | nếu | ngầm hiểu |
trong | inout | số nguyên | ý định | giao diện |
nội tại | Tốt bụng | len | hợp lý | mô-đun |
danh sách tên | vô hiệu hóa | chỉ có | nhà điều hành | không bắt buộc |
ngoài | tham số | tạm ngừng | con trỏ | riêng tư |
chương trình | công cộng | thực tế | đệ quy | kết quả |
trở về | tiết kiệm | chọn trường hợp | dừng lại | chương trình con |
Mục tiêu | sau đó | kiểu | kiểu() | sử dụng |
Ở đâu | Trong khi | |||
Các từ khóa liên quan đến I / O | ||||
xóa lùi | đóng | endfile | định dạng | hỏi thăm |
mở | in | đọc | tua lại | Viết |
Fortran cung cấp năm kiểu dữ liệu nội tại, tuy nhiên, bạn cũng có thể lấy các kiểu dữ liệu của riêng mình. Năm loại nội tại là -
- Kiểu số nguyên
- Loại thực
- Loại phức tạp
- Loại logic
- Loại ký tự
Loại số nguyên
Các kiểu số nguyên chỉ có thể chứa các giá trị nguyên. Ví dụ sau trích xuất giá trị lớn nhất có thể được giữ trong một số nguyên bốn byte thông thường:
program testingInt
implicit none
integer :: largeval
print *, huge(largeval)
end program testingInt
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
2147483647
Lưu ý rằng huge()hàm cung cấp số lớn nhất có thể được giữ bởi kiểu dữ liệu số nguyên cụ thể. Bạn cũng có thể chỉ định số byte bằng cách sử dụngkindngười chỉ định. Ví dụ sau đây chứng minh điều này -
program testingInt
implicit none
!two byte integer
integer(kind = 2) :: shortval
!four byte integer
integer(kind = 4) :: longval
!eight byte integer
integer(kind = 8) :: verylongval
!sixteen byte integer
integer(kind = 16) :: veryverylongval
!default integer
integer :: defval
print *, huge(shortval)
print *, huge(longval)
print *, huge(verylongval)
print *, huge(veryverylongval)
print *, huge(defval)
end program testingInt
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647
Loại thực
Nó lưu trữ các số dấu phẩy động, chẳng hạn như 2.0, 3.1415, -100.876, v.v.
Theo truyền thống, có hai loại thực khác nhau, mặc định real gõ và double precision kiểu.
Tuy nhiên, Fortran 90/95 cung cấp nhiều quyền kiểm soát hơn đối với độ chính xác của các kiểu dữ liệu số nguyên và thực thông qua kind specifier, mà chúng ta sẽ nghiên cứu trong chương về Số.
Ví dụ sau cho thấy việc sử dụng kiểu dữ liệu thực:
program division
implicit none
! Define real variables
real :: p, q, realRes
! Define integer variables
integer :: i, j, intRes
! Assigning values
p = 2.0
q = 3.0
i = 2
j = 3
! floating point division
realRes = p/q
intRes = i/j
print *, realRes
print *, intRes
end program division
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
0.666666687
0
Loại phức tạp
Điều này được sử dụng để lưu trữ các số phức. Một số phức có hai phần, phần thực và phần ảo. Hai đơn vị lưu trữ số liên tiếp lưu trữ hai phần này.
Ví dụ: số phức (3.0, -5.0) bằng 3.0 - 5.0i
Chúng ta sẽ thảo luận chi tiết hơn về các loại Phức tạp, trong chương Số.
Loại logic
Chỉ có hai giá trị logic: .true. và .false.
Loại ký tự
Kiểu ký tự lưu trữ các ký tự và chuỗi. Độ dài của chuỗi có thể được chỉ định bởi len specifier. Nếu không có độ dài nào được chỉ định, nó là 1.
For example,
character (len = 40) :: name
name = “Zara Ali”
Cách diễn đạt, name(1:4) sẽ cung cấp cho chuỗi con "Zara".
Nhập ngầm
Các phiên bản cũ hơn của Fortran cho phép một tính năng được gọi là nhập ngầm, tức là bạn không phải khai báo các biến trước khi sử dụng. Nếu một biến không được khai báo, thì ký tự đầu tiên trong tên của nó sẽ xác định kiểu của nó.
Các tên biến bắt đầu bằng i, j, k, l, m hoặc n, được coi là dành cho biến số nguyên và các tên khác là biến thực. Tuy nhiên, bạn phải khai báo tất cả các biến vì đây là cách lập trình tốt. Vì vậy, bạn bắt đầu chương trình của mình với câu lệnh -
implicit none
Câu lệnh này tắt tính năng nhập ẩn.
Một biến không là gì ngoài tên được đặt cho một vùng lưu trữ mà chương trình của chúng ta có thể thao tác. Mỗi biến phải có một kiểu cụ thể, xác định kích thước và cách bố trí bộ nhớ của biến; phạm vi giá trị có thể được lưu trữ trong bộ nhớ đó; và tập hợp các thao tác có thể áp dụng cho biến.
Tên của một biến có thể bao gồm các chữ cái, chữ số và ký tự gạch dưới. Tên trong Fortran phải tuân theo các quy tắc sau:
Nó không được dài hơn 31 ký tự.
Nó phải bao gồm các ký tự chữ và số (tất cả các chữ cái trong bảng chữ cái và các chữ số từ 0 đến 9) và dấu gạch dưới (_).
Ký tự đầu tiên của tên phải là một chữ cái.
Tên không phân biệt chữ hoa chữ thường.
Dựa trên các kiểu cơ bản được giải thích trong chương trước, sau đây là các kiểu biến:
Sr.No | Loại & Mô tả |
---|---|
1 | Integer Nó chỉ có thể chứa các giá trị số nguyên. |
2 | Real Nó lưu trữ các số dấu phẩy động. |
3 | Complex Nó được sử dụng để lưu trữ các số phức. |
4 | Logical Nó lưu trữ các giá trị Boolean logic. |
5 | Character Nó lưu trữ các ký tự hoặc chuỗi. |
Sự định nghĩa biến
Các biến được khai báo ở đầu chương trình (hoặc chương trình con) trong câu lệnh khai báo kiểu.
Cú pháp khai báo biến như sau:
type-specifier :: variable_name
Ví dụ
integer :: total
real :: average
complex :: cx
logical :: done
character(len = 80) :: message ! a string of 80 characters
Sau đó, bạn có thể gán giá trị cho các biến này, như
total = 20000
average = 1666.67
done = .true.
message = “A big Hello from Tutorials Point”
cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
Bạn cũng có thể sử dụng chức năng nội tại cmplx, để gán giá trị cho một biến phức tạp -
cx = cmplx (1.0/2.0, -7.0) ! cx = 0.5 – 7.0i
cx = cmplx (x, y) ! cx = x + yi
Thí dụ
Ví dụ sau minh họa việc khai báo, gán và hiển thị biến trên màn hình:
program variableTesting
implicit none
! declaring variables
integer :: total
real :: average
complex :: cx
logical :: done
character(len=80) :: message ! a string of 80 characters
!assigning values
total = 20000
average = 1666.67
done = .true.
message = "A big Hello from Tutorials Point"
cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
Print *, total
Print *, average
Print *, cx
Print *, done
Print *, message
end program variableTesting
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
20000
1666.67004
(3.00000000, 5.00000000 )
T
A big Hello from Tutorials Point
Các hằng số tham chiếu đến các giá trị cố định mà chương trình không thể thay đổi trong quá trình thực thi. Các giá trị cố định này còn được gọi làliterals.
Hằng số có thể thuộc bất kỳ kiểu dữ liệu cơ bản nào như hằng số nguyên, hằng số động, hằng số ký tự, hằng số phức hoặc chuỗi ký tự. Chỉ có hai hằng số logic:.true. và .false.
Các hằng được xử lý giống như các biến thông thường, ngoại trừ việc giá trị của chúng không thể được sửa đổi sau khi định nghĩa.
Các hằng số và chữ có tên
Có hai loại hằng số -
- Hằng số nghĩa đen
- Hằng số được đặt tên
Một hằng số theo nghĩa đen có một giá trị, nhưng không có tên.
Ví dụ, sau đây là các hằng chữ:
Kiểu | Thí dụ |
---|---|
Hằng số nguyên | 0 1 -1 300 123456789 |
Hằng số thực | 0,0 1,0 -1,0 123,456 7,1E + 10 -52,715E-30 |
Hằng số phức tạp | (0,0, 0,0) (-123,456E + 30, 987,654E-29) |
Hằng số logic | .thật. .sai. |
Hằng số ký tự | "PQR" "a" "123'abc $% # @!" " một câu trích dẫn "" " 'PQR' 'a' '123 "abc $% # @!' 'dấu nháy đơn' ' |
Hằng số được đặt tên có giá trị cũng như tên.
Hằng số được đặt tên phải được khai báo ở đầu chương trình hoặc thủ tục, giống như khai báo kiểu biến, cho biết tên và kiểu của nó. Các hằng được đặt tên được khai báo với thuộc tính tham số. Ví dụ,
real, parameter :: pi = 3.1415927
Thí dụ
Chương trình sau đây tính toán độ dời do chuyển động thẳng đứng dưới tác dụng của trọng lực.
program gravitationalDisp
! this program calculates vertical motion under gravity
implicit none
! gravitational acceleration
real, parameter :: g = 9.81
! variable declaration
real :: s ! displacement
real :: t ! time
real :: u ! initial speed
! assigning values
t = 5.0
u = 50
! displacement
s = u * t - g * (t**2) / 2
! output
print *, "Time = ", t
print *, 'Displacement = ',s
end program gravitationalDisp
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
Time = 5.00000000
Displacement = 127.374992
Một toán tử là một ký hiệu yêu cầu trình biên dịch thực hiện các thao tác toán học hoặc logic cụ thể. Fortran cung cấp các loại toán tử sau:
- Toán tử số học
- Toán tử quan hệ
- Toán tử logic
Chúng ta hãy xem xét từng loại toán tử này.
Toán tử số học
Bảng sau hiển thị tất cả các toán tử số học được hỗ trợ bởi Fortran. Giả sử biếnA giữ 5 và biến B giữ 3 rồi -
Hiển thị các ví dụ
Nhà điều hành | Sự miêu tả | Thí dụ |
---|---|---|
+ | Toán tử Phép cộng, thêm hai toán hạng. | A + B sẽ cho 8 |
- | Toán tử phép trừ, trừ toán hạng thứ hai với toán hạng đầu tiên. | A - B sẽ cho 2 |
* | Toán tử nhân, nhân cả hai toán hạng. | A * B sẽ cho 15 |
/ | Toán tử chia, chia tử số cho tử số. | A / B sẽ cho 1 |
** | Toán tử lũy thừa, nâng một toán hạng lên lũy thừa của toán hạng kia. | A ** B sẽ cho 125 |
Toán tử quan hệ
Bảng sau hiển thị tất cả các toán tử quan hệ được hỗ trợ bởi Fortran. Giả sử biếnA giữ 10 và biến B giữ 20, sau đó -
Hiển thị các ví dụ
Nhà điều hành | Tương đương | Sự miêu tả | Thí dụ |
---|---|---|---|
== | .eq. | Kiểm tra xem giá trị của hai toán hạng có bằng nhau hay không, nếu có thì điều kiện trở thành true. | (A == B) không đúng. |
/ = | .ne. | Kiểm tra xem giá trị của hai toán hạng có bằng nhau hay không, nếu các giá trị không bằng nhau thì điều kiện trở thành true. | (A! = B) là đúng. |
> | .gt. | Kiểm tra xem giá trị của toán hạng bên trái có lớn hơn giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. | (A> B) là không đúng. |
< | .lt. | Kiểm tra xem giá trị của toán hạng bên trái có nhỏ hơn giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. | (A <B) là đúng. |
> = | .ge. | Kiểm tra xem giá trị của toán hạng bên trái có lớn hơn hoặc bằng giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. | (A> = B) là không đúng. |
<= | .le. | Kiểm tra xem giá trị của toán hạng bên trái có nhỏ hơn hoặc bằng giá trị của toán hạng bên phải hay không, nếu có thì điều kiện trở thành true. | (A <= B) là đúng. |
Toán tử logic
Các toán tử logic trong Fortran chỉ hoạt động trên các giá trị logic .true. và .false.
Bảng sau đây cho thấy tất cả các toán tử logic được Fortran hỗ trợ. Giả sử biến A giữ .true. và biến B giữ .false. , sau đó -
Hiển thị các ví dụ
Nhà điều hành | Sự miêu tả | Thí dụ |
---|---|---|
.và. | Được gọi là toán tử logic AND. Nếu cả hai toán hạng đều khác 0, thì điều kiện trở thành true. | (A. Và. B) là sai. |
.hoặc là. | Được gọi là Toán tử logic HOẶC. Nếu bất kỳ toán hạng nào trong hai toán hạng khác 0, thì điều kiện trở thành true. | (A. Hoặc B) là đúng. |
.không phải. | Được gọi là Toán tử logic NOT. Sử dụng để đảo ngược trạng thái logic của toán hạng của nó. Nếu một điều kiện là đúng thì toán tử logic NOT sẽ sai. | ! (A. Và. B) là đúng. |
.eqv. | Được gọi là Toán tử TƯƠNG ĐƯƠNG logic. Được sử dụng để kiểm tra sự tương đương của hai giá trị logic. | (A .eqv. B) là sai. |
.neqv. | Được gọi là toán tử logic KHÔNG TƯƠNG ĐƯƠNG. Được sử dụng để kiểm tra sự không tương đương của hai giá trị logic. | (A .neqv. B) là đúng. |
Quyền ưu tiên của các nhà khai thác ở Fortran
Mức độ ưu tiên của toán tử xác định nhóm các từ trong một biểu thức. Điều này ảnh hưởng đến cách một biểu thức được đánh giá. Các toán tử nhất định có quyền ưu tiên cao hơn những toán tử khác; ví dụ, toán tử nhân có quyền ưu tiên cao hơn toán tử cộng.
Ví dụ: x = 7 + 3 * 2; ở đây, x được gán 13, không phải 20 vì toán tử * có mức độ ưu tiên cao hơn +, vì vậy đầu tiên nó được nhân với 3 * 2 và sau đó cộng thành 7.
Ở đây, các toán tử có mức độ ưu tiên cao nhất xuất hiện ở đầu bảng, những toán tử có mức độ ưu tiên thấp nhất xuất hiện ở cuối bảng. Trong một biểu thức, các toán tử có mức độ ưu tiên cao hơn sẽ được đánh giá đầu tiên.
Hiển thị các ví dụ
thể loại | Nhà điều hành | Sự liên kết |
---|---|---|
Không logic và dấu phủ định | .không phải. (-) | Trái sang phải |
Luỹ thừa | ** | Trái sang phải |
Phép nhân | * / | Trái sang phải |
Phụ gia | + - | Trái sang phải |
Quan hệ | <<=>> = | Trái sang phải |
Bình đẳng | == / = | Trái sang phải |
Logic AND | .và. | Trái sang phải |
Logic HOẶC | .hoặc là. | Trái sang phải |
Chuyển nhượng | = | Phải sang trái |
Cấu trúc ra quyết định yêu cầu người lập trình chỉ định một hoặc nhiều điều kiện để được đánh giá hoặc kiểm tra bởi chương trình, cùng với một câu lệnh hoặc các câu lệnh sẽ được thực thi, nếu điều kiện được xác định là đúng và tùy ý, các câu lệnh khác sẽ được thực thi nếu điều kiện được xác định là sai.
Sau đây là dạng chung của cấu trúc ra quyết định điển hình được tìm thấy trong hầu hết các ngôn ngữ lập trình:
Fortran cung cấp các loại cấu trúc ra quyết định sau.
Sr.No | Tuyên bố & Mô tả |
---|---|
1 | Nếu… thì xây dựng An if… then… end if câu lệnh bao gồm một biểu thức logic theo sau bởi một hoặc nhiều câu lệnh. |
2 | Nếu… thì… cấu tạo khác An if… then câu lệnh có thể được theo sau bởi một tùy chọn else statement, thực thi khi biểu thức logic sai. |
3 | if ... else if ... else Câu lệnh An if cấu trúc câu lệnh có thể có một hoặc nhiều tùy chọn else-ifcấu trúc. Khi màif điều kiện không thành công, ngay sau đó else-ifđược thực thi. Khi màelse-if cũng thất bại, người kế nhiệm của nó else-if câu lệnh (nếu có) được thực thi, v.v. |
4 | lồng nhau nếu cấu trúc Bạn có thể sử dụng một if hoặc là else if tuyên bố bên trong khác if hoặc là else if các câu lệnh). |
5 | chọn cấu trúc trường hợp A select case câu lệnh cho phép một biến được kiểm tra tính bình đẳng với một danh sách các giá trị. |
6 | cấu trúc trường hợp chọn lồng nhau Bạn có thể sử dụng một select case tuyên bố bên trong khác select case các câu lệnh). |
Có thể có một tình huống, khi bạn cần thực thi một khối mã nhiều lần. Nói chung, các câu lệnh được thực hiện tuần tự: Câu lệnh đầu tiên trong một hàm được thực hiện đầu tiên, tiếp theo là câu lệnh thứ hai, v.v.
Các ngôn ngữ lập trình cung cấp các cấu trúc điều khiển khác nhau cho phép các đường dẫn thực thi phức tạp hơn.
Câu lệnh lặp cho phép chúng ta thực hiện một câu lệnh hoặc một nhóm câu lệnh nhiều lần và sau đây là dạng chung của câu lệnh lặp trong hầu hết các ngôn ngữ lập trình:
Fortran cung cấp các loại cấu trúc vòng lặp sau để xử lý các yêu cầu lặp. Nhấp vào các liên kết sau để kiểm tra chi tiết của chúng.
Sr.No | Loại vòng lặp & Mô tả |
---|---|
1 | làm vòng lặp Cấu trúc này cho phép một câu lệnh hoặc một chuỗi câu lệnh được thực hiện lặp đi lặp lại, trong khi một điều kiện đã cho là đúng. |
2 | vòng lặp do while Lặp lại một câu lệnh hoặc một nhóm câu lệnh trong khi một điều kiện đã cho là đúng. Nó kiểm tra điều kiện trước khi thực thi phần thân của vòng lặp. |
3 | vòng lồng nhau Bạn có thể sử dụng một hoặc nhiều cấu trúc vòng lặp bên trong bất kỳ cấu trúc vòng lặp nào khác. |
Tuyên bố kiểm soát vòng lặp
Các câu lệnh điều khiển vòng lặp thay đổi việc thực thi từ trình tự bình thường của nó. Khi việc thực thi rời khỏi một phạm vi, tất cả các đối tượng tự động được tạo trong phạm vi đó sẽ bị phá hủy.
Fortran hỗ trợ các câu lệnh điều khiển sau. Nhấp vào các liên kết sau để kiểm tra chi tiết của chúng.
Sr.No | Tuyên bố & Mô tả Kiểm soát |
---|---|
1 | lối ra Nếu câu lệnh thoát được thực thi, vòng lặp sẽ được thoát và việc thực thi chương trình tiếp tục ở câu lệnh thực thi đầu tiên sau câu lệnh end do. |
2 | đi xe đạp Nếu một câu lệnh chu trình được thực hiện, chương trình sẽ tiếp tục khi bắt đầu lần lặp tiếp theo. |
3 | dừng lại Nếu bạn muốn dừng việc thực thi chương trình của mình, bạn có thể chèn một câu lệnh dừng |
Các con số trong Fortran được đại diện bởi ba kiểu dữ liệu nội tại -
- Kiểu số nguyên
- Loại thực
- Loại phức tạp
Loại số nguyên
Các kiểu số nguyên chỉ có thể chứa các giá trị nguyên. Ví dụ sau đây trích xuất giá trị lớn nhất có thể được giữ trong một số nguyên bốn byte thông thường:
program testingInt
implicit none
integer :: largeval
print *, huge(largeval)
end program testingInt
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
2147483647
Xin lưu ý rằng huge()hàm cung cấp số lớn nhất có thể được giữ bởi kiểu dữ liệu số nguyên cụ thể. Bạn cũng có thể chỉ định số byte bằng cách sử dụngkindngười chỉ định. Ví dụ sau đây chứng minh điều này -
program testingInt
implicit none
!two byte integer
integer(kind = 2) :: shortval
!four byte integer
integer(kind = 4) :: longval
!eight byte integer
integer(kind = 8) :: verylongval
!sixteen byte integer
integer(kind = 16) :: veryverylongval
!default integer
integer :: defval
print *, huge(shortval)
print *, huge(longval)
print *, huge(verylongval)
print *, huge(veryverylongval)
print *, huge(defval)
end program testingInt
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647
Loại thực
Nó lưu trữ các số dấu phẩy động, chẳng hạn như 2.0, 3.1415, -100.876, v.v.
Theo truyền thống, có hai real loại: loại thực mặc định và double precision kiểu.
Tuy nhiên, Fortran 90/95 cung cấp nhiều quyền kiểm soát hơn đối với độ chính xác của các kiểu dữ liệu số nguyên và thực thông qua kind specifier, mà chúng ta sẽ nghiên cứu ngay sau đây.
Ví dụ sau cho thấy việc sử dụng kiểu dữ liệu thực:
program division
implicit none
! Define real variables
real :: p, q, realRes
! Define integer variables
integer :: i, j, intRes
! Assigning values
p = 2.0
q = 3.0
i = 2
j = 3
! floating point division
realRes = p/q
intRes = i/j
print *, realRes
print *, intRes
end program division
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
0.666666687
0
Loại phức tạp
Điều này được sử dụng để lưu trữ các số phức. Một số phức có hai phần: phần thực và phần ảo. Hai đơn vị lưu trữ số liên tiếp lưu trữ hai phần này.
Ví dụ: số phức (3.0, -5.0) bằng 3.0 - 5.0i
Hàm chung cmplx()tạo ra một số phức. Nó tạo ra một kết quả là phần thực và phần ảo là độ chính xác duy nhất, bất kể loại đối số đầu vào.
program createComplex
implicit none
integer :: i = 10
real :: x = 5.17
print *, cmplx(i, x)
end program createComplex
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
(10.0000000, 5.17000008)
Chương trình sau đây biểu diễn số học phức:
program ComplexArithmatic
implicit none
complex, parameter :: i = (0, 1) ! sqrt(-1)
complex :: x, y, z
x = (7, 8);
y = (5, -7)
write(*,*) i * x * y
z = x + y
print *, "z = x + y = ", z
z = x - y
print *, "z = x - y = ", z
z = x * y
print *, "z = x * y = ", z
z = x / y
print *, "z = x / y = ", z
end program ComplexArithmatic
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
(9.00000000, 91.0000000)
z = x + y = (12.0000000, 1.00000000)
z = x - y = (2.00000000, 15.0000000)
z = x * y = (91.0000000, -9.00000000)
z = x / y = (-0.283783793, 1.20270276)
Phạm vi, độ chính xác và kích thước của các con số
Phạm vi về số nguyên, độ chính xác và kích thước của số dấu phẩy động phụ thuộc vào số lượng bit được phân bổ cho kiểu dữ liệu cụ thể.
Bảng sau đây hiển thị số bit và phạm vi cho các số nguyên:
Số lượng bit | Gia trị lơn nhât | Lý do |
---|---|---|
64 | 9.223.372.036.854.774.807 | (2 ** 63) –1 |
32 | 2.147.483.647 | (2 ** 31) –1 |
Bảng sau đây hiển thị số bit, giá trị nhỏ nhất và lớn nhất và độ chính xác của các số thực.
Số lượng bit | Giá trị lớn nhất | Giá trị nhỏ nhất | Độ chính xác |
---|---|---|---|
64 | 0,8E + 308 | 0,5E – 308 | 15–18 |
32 | 1,7E + 38 | 0,3E – 38 | 6-9 |
Các ví dụ sau đây chứng minh điều này -
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e+40
y = 3.73e+40
z = x * y
print *, z
end program rangePrecision
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
x = 1.5e+40
1
Error : Real constant overflows its kind at (1)
main.f95:5.12:
y = 3.73e+40
1
Error : Real constant overflows its kind at (1)
Bây giờ chúng ta hãy sử dụng một số nhỏ hơn -
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e+20
y = 3.73e+20
z = x * y
print *, z
z = x/y
print *, z
end program rangePrecision
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Infinity
0.402144760
Bây giờ chúng ta hãy xem quy trình dưới đây -
program rangePrecision
implicit none
real:: x, y, z
x = 1.5e-30
y = 3.73e-60
z = x * y
print *, z
z = x/y
print *, z
end program rangePrecision
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
y = 3.73e-60
1
Warning : Real constant underflows its kind at (1)
Executing the program....
$demo
0.00000000E+00
Infinity
Bộ chỉ định loại
Trong lập trình khoa học, người ta thường cần biết phạm vi và độ chính xác của dữ liệu của nền tảng phần cứng mà công việc đang được thực hiện.
Chức năng nội tại kind() cho phép bạn truy vấn chi tiết về các biểu diễn dữ liệu của phần cứng trước khi chạy một chương trình.
program kindCheck
implicit none
integer :: i
real :: r
complex :: cp
print *,' Integer ', kind(i)
print *,' Real ', kind(r)
print *,' Complex ', kind(cp)
end program kindCheck
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Integer 4
Real 4
Complex 4
Bạn cũng có thể kiểm tra loại của tất cả các loại dữ liệu -
program checkKind
implicit none
integer :: i
real :: r
character :: c
logical :: lg
complex :: cp
print *,' Integer ', kind(i)
print *,' Real ', kind(r)
print *,' Complex ', kind(cp)
print *,' Character ', kind(c)
print *,' Logical ', kind(lg)
end program checkKind
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Integer 4
Real 4
Complex 4
Character 1
Logical 4
Ngôn ngữ Fortran có thể coi các ký tự là ký tự đơn hoặc các chuỗi liền nhau.
Các ký tự có thể là bất kỳ ký hiệu nào được lấy từ bộ ký tự cơ bản, tức là từ các chữ cái, chữ số thập phân, dấu gạch dưới và 21 ký tự đặc biệt.
Hằng ký tự là một chuỗi ký tự có giá trị cố định.
Kiểu dữ liệu nội tại characterlưu trữ các ký tự và chuỗi. Độ dài của chuỗi có thể được chỉ định bởilenngười chỉ định. Nếu không có độ dài nào được chỉ định, nó là 1. Bạn có thể tham chiếu các ký tự riêng lẻ trong một chuỗi tham chiếu theo vị trí; ký tự ngoài cùng bên trái ở vị trí 1.
Tuyên bố nhân vật
Khai báo dữ liệu kiểu ký tự giống như các biến khác:
type-specifier :: variable_name
Ví dụ,
character :: reply, sex
bạn có thể gán một giá trị như,
reply = ‘N’
sex = ‘F’
Ví dụ sau minh họa việc khai báo và sử dụng kiểu dữ liệu ký tự:
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 25)::greetings
title = 'Mr. '
firstname = 'Rowan '
surname = 'Atkinson'
greetings = 'A big hello from Mr. Bean'
print *, 'Here is ', title, firstname, surname
print *, greetings
end program hello
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Here is Mr. Rowan Atkinson
A big hello from Mr. Bean
Kết hợp các ký tự
Toán tử nối //, nối các ký tự.
Ví dụ sau đây chứng minh điều này -
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 40):: name
character(len = 25)::greetings
title = 'Mr. '
firstname = 'Rowan '
surname = 'Atkinson'
name = title//firstname//surname
greetings = 'A big hello from Mr. Bean'
print *, 'Here is ', name
print *, greetings
end program hello
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Here is Mr.Rowan Atkinson
A big hello from Mr.Bean
Một số chức năng ký tự
Bảng sau đây cho thấy một số hàm ký tự thường được sử dụng cùng với mô tả:
Sr.No | Mô tả chức năng |
---|---|
1 | len(string) Nó trả về độ dài của một chuỗi ký tự |
2 | index(string,sustring) Nó tìm vị trí của một chuỗi con trong một chuỗi khác, trả về 0 nếu không tìm thấy. |
3 | achar(int) Nó chuyển đổi một số nguyên thành một ký tự |
4 | iachar(c) Nó chuyển đổi một ký tự thành một số nguyên |
5 | trim(string) Nó trả về chuỗi đã loại bỏ các khoảng trống ở cuối. |
6 | scan(string, chars) Nó tìm kiếm "chuỗi" từ trái sang phải (trừ khi back = .true.) Cho lần xuất hiện đầu tiên của bất kỳ ký tự nào có trong "ký tự". Nó trả về một số nguyên cho vị trí của ký tự đó hoặc bằng 0 nếu không tìm thấy ký tự nào trong "ký tự". |
7 | verify(string, chars) Nó quét "chuỗi" từ trái sang phải (trừ khi back = .true.) Cho lần xuất hiện đầu tiên của bất kỳ ký tự nào không có trong "ký tự". Nó trả về một số nguyên cho vị trí của ký tự đó hoặc bằng 0 nếu chỉ tìm thấy các ký tự trong "ký tự" |
số 8 | adjustl(string) Nó còn lại biện minh cho các ký tự có trong "chuỗi" |
9 | adjustr(string) Nó đúng minh chứng cho các ký tự có trong "chuỗi" |
10 | len_trim(string) Nó trả về một số nguyên bằng độ dài của "string" (len (string)) trừ đi số khoảng trống ở cuối |
11 | repeat(string,ncopy) Nó trả về một chuỗi có độ dài bằng "ncopy" nhân với độ dài của "chuỗi" và chứa các bản sao được nối "ncopy" của "chuỗi" |
ví dụ 1
Ví dụ này cho thấy việc sử dụng index chức năng -
program testingChars
implicit none
character (80) :: text
integer :: i
text = 'The intrinsic data type character stores characters and strings.'
i=index(text,'character')
if (i /= 0) then
print *, ' The word character found at position ',i
print *, ' in text: ', text
end if
end program testingChars
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
The word character found at position 25
in text : The intrinsic data type character stores characters and strings.
Ví dụ 2
Ví dụ này minh họa việc sử dụng trim chức năng -
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 25)::greetings
title = 'Mr.'
firstname = 'Rowan'
surname = 'Atkinson'
print *, 'Here is', title, firstname, surname
print *, 'Here is', trim(title),' ',trim(firstname),' ', trim(surname)
end program hello
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Here isMr. Rowan Atkinson
Here isMr. Rowan Atkinson
Ví dụ 3
Ví dụ này minh họa việc sử dụng achar chức năng -
program testingChars
implicit none
character:: ch
integer:: i
do i = 65, 90
ch = achar(i)
print*, i, ' ', ch
end do
end program testingChars
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
65 A
66 B
67 C
68 D
69 E
70 F
71 G
72 H
73 I
74 J
75 K
76 L
77 M
78 N
79 O
80 P
81 Q
82 R
83 S
84 T
85 U
86 V
87 W
88 X
89 Y
90 Z
Kiểm tra Thứ tự Lexical của các ký tự
Các hàm sau xác định chuỗi ký tự từ vựng:
Sr.No | Mô tả chức năng |
---|---|
1 | lle(char, char) So sánh liệu ký tự đầu tiên có từ vựng nhỏ hơn hoặc bằng ký tự thứ hai hay không |
2 | lge(char, char) So sánh liệu ký tự đầu tiên lớn hơn hoặc bằng ký tự thứ hai |
3 | lgt(char, char) So sánh liệu ký tự đầu tiên có lớn hơn về mặt từ vựng so với ký tự thứ hai hay không |
4 | llt(char, char) So sánh xem ký tự đầu tiên có ít từ vựng hơn ký tự thứ hai hay không |
Example 4
Hàm sau thể hiện việc sử dụng:
program testingChars
implicit none
character:: a, b, c
a = 'A'
b = 'a'
c = 'B'
if(lgt(a,b)) then
print *, 'A is lexically greater than a'
else
print *, 'a is lexically greater than A'
end if
if(lgt(a,c)) then
print *, 'A is lexically greater than B'
else
print *, 'B is lexically greater than A'
end if
if(llt(a,b)) then
print *, 'A is lexically less than a'
end if
if(llt(a,c)) then
print *, 'A is lexically less than B'
end if
end program testingChars
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
a is lexically greater than A
B is lexically greater than A
A is lexically less than a
A is lexically less than B
Ngôn ngữ Fortran có thể coi các ký tự là ký tự đơn hoặc các chuỗi liền nhau.
Một chuỗi ký tự có thể chỉ dài một ký tự hoặc thậm chí có thể có độ dài bằng không. Trong Fortran, hằng số ký tự được đưa ra giữa một cặp dấu ngoặc kép hoặc đơn.
Kiểu dữ liệu nội tại characterlưu trữ các ký tự và chuỗi. Độ dài của chuỗi có thể được chỉ định bởilen specifier. Nếu không có độ dài nào được chỉ định, nó là 1. Bạn có thể tham chiếu các ký tự riêng lẻ trong một chuỗi tham chiếu theo vị trí; ký tự ngoài cùng bên trái ở vị trí 1.
Khai báo chuỗi
Khai báo một chuỗi cũng giống như các biến khác -
type-specifier :: variable_name
Ví dụ,
Character(len = 20) :: firstname, surname
bạn có thể gán một giá trị như,
character (len = 40) :: name
name = “Zara Ali”
Ví dụ sau minh họa việc khai báo và sử dụng kiểu dữ liệu ký tự:
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 25)::greetings
title = 'Mr.'
firstname = 'Rowan'
surname = 'Atkinson'
greetings = 'A big hello from Mr. Beans'
print *, 'Here is', title, firstname, surname
print *, greetings
end program hello
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Here isMr. Rowan Atkinson
A big hello from Mr. Bean
Kết nối chuỗi
Toán tử nối //, nối các chuỗi.
Ví dụ sau đây chứng minh điều này -
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 40):: name
character(len = 25)::greetings
title = 'Mr.'
firstname = 'Rowan'
surname = 'Atkinson'
name = title//firstname//surname
greetings = 'A big hello from Mr. Beans'
print *, 'Here is', name
print *, greetings
end program hello
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Here is Mr. Rowan Atkinson
A big hello from Mr. Bean
Giải nén chuỗi con
Trong Fortran, bạn có thể trích xuất một chuỗi con từ một chuỗi bằng cách lập chỉ mục chuỗi, cho chỉ số bắt đầu và kết thúc của chuỗi con trong một cặp dấu ngoặc. Đây được gọi là chỉ định mức độ.
Ví dụ sau cho thấy cách trích xuất chuỗi con 'world' từ chuỗi 'hello world' -
program subString
character(len = 11)::hello
hello = "Hello World"
print*, hello(7:11)
end program subString
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
World
Thí dụ
Ví dụ sau sử dụng date_and_timehàm cung cấp chuỗi ngày và giờ. Chúng tôi sử dụng các chỉ định mức độ để trích xuất năm, ngày, tháng, giờ, phút và thông tin thứ hai một cách riêng biệt.
program datetime
implicit none
character(len = 8) :: dateinfo ! ccyymmdd
character(len = 4) :: year, month*2, day*2
character(len = 10) :: timeinfo ! hhmmss.sss
character(len = 2) :: hour, minute, second*6
call date_and_time(dateinfo, timeinfo)
! let’s break dateinfo into year, month and day.
! dateinfo has a form of ccyymmdd, where cc = century, yy = year
! mm = month and dd = day
year = dateinfo(1:4)
month = dateinfo(5:6)
day = dateinfo(7:8)
print*, 'Date String:', dateinfo
print*, 'Year:', year
print *,'Month:', month
print *,'Day:', day
! let’s break timeinfo into hour, minute and second.
! timeinfo has a form of hhmmss.sss, where h = hour, m = minute
! and s = second
hour = timeinfo(1:2)
minute = timeinfo(3:4)
second = timeinfo(5:10)
print*, 'Time String:', timeinfo
print*, 'Hour:', hour
print*, 'Minute:', minute
print*, 'Second:', second
end program datetime
Khi bạn biên dịch và thực thi chương trình trên, nó sẽ cung cấp thông tin ngày và giờ chi tiết -
Date String: 20140803
Year: 2014
Month: 08
Day: 03
Time String: 075835.466
Hour: 07
Minute: 58
Second: 35.466
Cắt tỉa chuỗi
Các trim hàm nhận một chuỗi và trả về chuỗi đầu vào sau khi loại bỏ tất cả các khoảng trống ở cuối.
Thí dụ
program trimString
implicit none
character (len = *), parameter :: fname="Susanne", sname="Rizwan"
character (len = 20) :: fullname
fullname = fname//" "//sname !concatenating the strings
print*,fullname,", the beautiful dancer from the east!"
print*,trim(fullname),", the beautiful dancer from the east!"
end program trimString
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Susanne Rizwan , the beautiful dancer from the east!
Susanne Rizwan, the beautiful dancer from the east!
Điều chỉnh trái và phải của chuỗi
Chức năng adjustl lấy một chuỗi và trả về nó bằng cách loại bỏ các khoảng trống ở đầu và nối chúng dưới dạng các khoảng trống ở cuối.
Chức năng adjustr lấy một chuỗi và trả về nó bằng cách loại bỏ các khoảng trống ở cuối và nối chúng dưới dạng các khoảng trống ở đầu.
Thí dụ
program hello
implicit none
character(len = 15) :: surname, firstname
character(len = 6) :: title
character(len = 40):: name
character(len = 25):: greetings
title = 'Mr. '
firstname = 'Rowan'
surname = 'Atkinson'
greetings = 'A big hello from Mr. Beans'
name = adjustl(title)//adjustl(firstname)//adjustl(surname)
print *, 'Here is', name
print *, greetings
name = adjustr(title)//adjustr(firstname)//adjustr(surname)
print *, 'Here is', name
print *, greetings
name = trim(title)//trim(firstname)//trim(surname)
print *, 'Here is', name
print *, greetings
end program hello
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Here is Mr. Rowan Atkinson
A big hello from Mr. Bean
Here is Mr. Rowan Atkinson
A big hello from Mr. Bean
Here is Mr.RowanAtkinson
A big hello from Mr. Bean
Tìm kiếm một chuỗi con trong một chuỗi
Hàm chỉ mục nhận hai chuỗi và kiểm tra xem chuỗi thứ hai có phải là chuỗi con của chuỗi đầu tiên hay không. Nếu đối số thứ hai là chuỗi con của đối số đầu tiên, thì nó trả về một số nguyên là chỉ số bắt đầu của chuỗi thứ hai trong chuỗi đầu tiên, nếu không nó trả về số không.
Thí dụ
program hello
implicit none
character(len=30) :: myString
character(len=10) :: testString
myString = 'This is a test'
testString = 'test'
if(index(myString, testString) == 0)then
print *, 'test is not found'
else
print *, 'test is found at index: ', index(myString, testString)
end if
end program hello
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
test is found at index: 11
Mảng có thể lưu trữ một tập hợp tuần tự có kích thước cố định của các phần tử cùng kiểu. Mảng được sử dụng để lưu trữ một tập hợp dữ liệu, nhưng thường hữu ích hơn nếu coi một mảng là một tập hợp các biến cùng kiểu.
Tất cả các mảng bao gồm các vị trí bộ nhớ liền nhau. Địa chỉ thấp nhất tương ứng với phần tử đầu tiên và địa chỉ cao nhất cho phần tử cuối cùng.
Số (1) | Số (2) | Số (3) | Số (4) | … |
Mảng có thể là một chiều (như vectơ), hai chiều (như ma trận) và Fortran cho phép bạn tạo mảng tối đa 7 chiều.
Khai báo Mảng
Mảng được khai báo với dimension thuộc tính.
Ví dụ, để khai báo mảng một chiều có tên là số, gồm các số thực có chứa 5 phần tử, bạn viết:
real, dimension(5) :: numbers
Các phần tử riêng lẻ của mảng được tham chiếu bằng cách chỉ định các chỉ số con của chúng. Phần tử đầu tiên của một mảng có một chỉ số con của một. Mảng số chứa năm biến số thực - số (1), số (2), số (3), số (4) và số (5).
Để tạo mảng hai chiều 5 x 5 gồm các số nguyên có tên là ma trận, bạn viết:
integer, dimension (5,5) :: matrix
Bạn cũng có thể khai báo một mảng với một số giới hạn dưới rõ ràng, ví dụ:
real, dimension(2:6) :: numbers
integer, dimension (-3:2,0:4) :: matrix
Gán giá trị
Bạn có thể chỉ định giá trị cho từng thành viên, chẳng hạn như,
numbers(1) = 2.0
hoặc, bạn có thể sử dụng một vòng lặp,
do i =1,5
numbers(i) = i * 2.0
end do
Các phần tử mảng một chiều có thể được gán trực tiếp các giá trị bằng cách sử dụng một ký hiệu viết tay ngắn, được gọi là hàm tạo mảng, như,
numbers = (/1.5, 3.2,4.5,0.9,7.2 /)
please note that there are no spaces allowed between the brackets ‘( ‘and the back slash ‘/’
Thí dụ
Ví dụ sau đây minh họa các khái niệm đã thảo luận ở trên.
program arrayProg
real :: numbers(5) !one dimensional integer array
integer :: matrix(3,3), i , j !two dimensional real array
!assigning some values to the array numbers
do i=1,5
numbers(i) = i * 2.0
end do
!display the values
do i = 1, 5
Print *, numbers(i)
end do
!assigning some values to the array matrix
do i=1,3
do j = 1, 3
matrix(i, j) = i+j
end do
end do
!display the values
do i=1,3
do j = 1, 3
Print *, matrix(i,j)
end do
end do
!short hand assignment
numbers = (/1.5, 3.2,4.5,0.9,7.2 /)
!display the values
do i = 1, 5
Print *, numbers(i)
end do
end program arrayProg
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
2.00000000
4.00000000
6.00000000
8.00000000
10.0000000
2
3
4
3
4
5
4
5
6
1.50000000
3.20000005
4.50000000
0.899999976
7.19999981
Một số thuật ngữ liên quan đến mảng
Bảng sau đây đưa ra một số thuật ngữ liên quan đến mảng:
Kỳ hạn | Ý nghĩa |
---|---|
Cấp | Nó là số thứ nguyên mà một mảng có. Ví dụ: đối với mảng có tên là ma trận, hạng là 2 và đối với mảng có tên là số, hạng là 1. |
Mức độ | Nó là số phần tử dọc theo một thứ nguyên. Ví dụ, số mảng có phạm vi 5 và ma trận có tên mảng có phạm vi 3 trong cả hai chiều. |
Hình dạng | Hình dạng của mảng là mảng số nguyên một chiều, chứa số phần tử (mức độ) trong mỗi chiều. Ví dụ, đối với ma trận mảng, hình dạng là (3, 3) và số mảng là (5). |
Kích thước | Nó là số phần tử mà một mảng chứa. Đối với ma trận mảng, nó là 9 và đối với số mảng, nó là 5. |
Chuyển Mảng sang Thủ tục
Bạn có thể truyền một mảng cho một thủ tục làm đối số. Ví dụ sau thể hiện khái niệm -
program arrayToProcedure
implicit none
integer, dimension (5) :: myArray
integer :: i
call fillArray (myArray)
call printArray(myArray)
end program arrayToProcedure
subroutine fillArray (a)
implicit none
integer, dimension (5), intent (out) :: a
! local variables
integer :: i
do i = 1, 5
a(i) = i
end do
end subroutine fillArray
subroutine printArray(a)
integer, dimension (5) :: a
integer::i
do i = 1, 5
Print *, a(i)
end do
end subroutine printArray
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
1
2
3
4
5
Trong ví dụ trên, chương trình con fillArray và printArray chỉ có thể được gọi với các mảng có kích thước là 5. Tuy nhiên, để viết các chương trình con có thể được sử dụng cho các mảng có kích thước bất kỳ, bạn có thể viết lại nó bằng kỹ thuật sau:
program arrayToProcedure
implicit none
integer, dimension (10) :: myArray
integer :: i
interface
subroutine fillArray (a)
integer, dimension(:), intent (out) :: a
integer :: i
end subroutine fillArray
subroutine printArray (a)
integer, dimension(:) :: a
integer :: i
end subroutine printArray
end interface
call fillArray (myArray)
call printArray(myArray)
end program arrayToProcedure
subroutine fillArray (a)
implicit none
integer,dimension (:), intent (out) :: a
! local variables
integer :: i, arraySize
arraySize = size(a)
do i = 1, arraySize
a(i) = i
end do
end subroutine fillArray
subroutine printArray(a)
implicit none
integer,dimension (:) :: a
integer::i, arraySize
arraySize = size(a)
do i = 1, arraySize
Print *, a(i)
end do
end subroutine printArray
Xin lưu ý rằng chương trình đang sử dụng size hàm lấy kích thước của mảng.
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
1
2
3
4
5
6
7
8
9
10
Phần mảng
Cho đến nay chúng ta đã tham chiếu đến toàn bộ mảng, Fortran cung cấp một cách dễ dàng để tham chiếu một số phần tử hoặc một phần của mảng, bằng cách sử dụng một câu lệnh duy nhất.
Để truy cập một phần mảng, bạn cần cung cấp giới hạn dưới và giới hạn trên của phần đó, cũng như một khoảng cách (gia số), cho tất cả các kích thước. Ký hiệu này được gọi làsubscript triplet:
array ([lower]:[upper][:stride], ...)
Khi không có giới hạn dưới và giới hạn trên được đề cập, nó sẽ mặc định theo phạm vi bạn đã khai báo và giá trị bước đi mặc định là 1.
Ví dụ sau thể hiện khái niệm -
program arraySubsection
real, dimension(10) :: a, b
integer:: i, asize, bsize
a(1:7) = 5.0 ! a(1) to a(7) assigned 5.0
a(8:) = 0.0 ! rest are 0.0
b(2:10:2) = 3.9
b(1:9:2) = 2.5
!display
asize = size(a)
bsize = size(b)
do i = 1, asize
Print *, a(i)
end do
do i = 1, bsize
Print *, b(i)
end do
end program arraySubsection
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
5.00000000
5.00000000
5.00000000
5.00000000
5.00000000
5.00000000
5.00000000
0.00000000E+00
0.00000000E+00
0.00000000E+00
2.50000000
3.90000010
2.50000000
3.90000010
2.50000000
3.90000010
2.50000000
3.90000010
2.50000000
3.90000010
Các chức năng nội tại của mảng
Fortran 90/95 cung cấp một số quy trình nội tại. Chúng có thể được chia thành 7 loại.
Phép nhân vectơ và ma trận
Reduction
Inquiry
Construction
Reshape
Manipulation
Location
A dynamic array là một mảng, kích thước của mảng đó không được biết tại thời điểm biên dịch, nhưng sẽ được biết vào thời điểm thực thi.
Mảng động được khai báo với thuộc tính allocatable.
Ví dụ,
real, dimension (:,:), allocatable :: darray
Thứ hạng của mảng, tức là, các kích thước phải được đề cập, tuy nhiên, để cấp phát bộ nhớ cho một mảng như vậy, bạn sử dụng allocate chức năng.
allocate ( darray(s1,s2) )
Sau khi mảng được sử dụng, trong chương trình, bộ nhớ được tạo sẽ được giải phóng bằng cách sử dụng deallocate chức năng
deallocate (darray)
Thí dụ
Ví dụ sau đây minh họa các khái niệm đã thảo luận ở trên.
program dynamic_array
implicit none
!rank is 2, but size not known
real, dimension (:,:), allocatable :: darray
integer :: s1, s2
integer :: i, j
print*, "Enter the size of the array:"
read*, s1, s2
! allocate memory
allocate ( darray(s1,s2) )
do i = 1, s1
do j = 1, s2
darray(i,j) = i*j
print*, "darray(",i,",",j,") = ", darray(i,j)
end do
end do
deallocate (darray)
end program dynamic_array
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
Enter the size of the array: 3,4
darray( 1 , 1 ) = 1.00000000
darray( 1 , 2 ) = 2.00000000
darray( 1 , 3 ) = 3.00000000
darray( 1 , 4 ) = 4.00000000
darray( 2 , 1 ) = 2.00000000
darray( 2 , 2 ) = 4.00000000
darray( 2 , 3 ) = 6.00000000
darray( 2 , 4 ) = 8.00000000
darray( 3 , 1 ) = 3.00000000
darray( 3 , 2 ) = 6.00000000
darray( 3 , 3 ) = 9.00000000
darray( 3 , 4 ) = 12.0000000
Sử dụng Tuyên bố Dữ liệu
Các data câu lệnh có thể được sử dụng để khởi tạo nhiều hơn một mảng hoặc khởi tạo phần mảng.
Cú pháp của câu lệnh dữ liệu là -
data variable / list / ...
Thí dụ
Ví dụ sau thể hiện khái niệm -
program dataStatement
implicit none
integer :: a(5), b(3,3), c(10),i, j
data a /7,8,9,10,11/
data b(1,:) /1,1,1/
data b(2,:)/2,2,2/
data b(3,:)/3,3,3/
data (c(i),i = 1,10,2) /4,5,6,7,8/
data (c(i),i = 2,10,2)/5*2/
Print *, 'The A array:'
do j = 1, 5
print*, a(j)
end do
Print *, 'The B array:'
do i = lbound(b,1), ubound(b,1)
write(*,*) (b(i,j), j = lbound(b,2), ubound(b,2))
end do
Print *, 'The C array:'
do j = 1, 10
print*, c(j)
end do
end program dataStatement
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
The A array:
7
8
9
10
11
The B array:
1 1 1
2 2 2
3 3 3
The C array:
4
2
5
2
6
2
7
2
8
2
Sử dụng Tuyên bố Vị trí
Các wherecâu lệnh cho phép bạn sử dụng một số phần tử của mảng trong một biểu thức, tùy thuộc vào kết quả của một số điều kiện logic. Nó cho phép thực hiện biểu thức, trên một phần tử, nếu điều kiện đã cho là đúng.
Thí dụ
Ví dụ sau thể hiện khái niệm -
program whereStatement
implicit none
integer :: a(3,5), i , j
do i = 1,3
do j = 1, 5
a(i,j) = j-i
end do
end do
Print *, 'The A array:'
do i = lbound(a,1), ubound(a,1)
write(*,*) (a(i,j), j = lbound(a,2), ubound(a,2))
end do
where( a<0 )
a = 1
elsewhere
a = 5
end where
Print *, 'The A array:'
do i = lbound(a,1), ubound(a,1)
write(*,*) (a(i,j), j = lbound(a,2), ubound(a,2))
end do
end program whereStatement
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
The A array:
0 1 2 3 4
-1 0 1 2 3
-2 -1 0 1 2
The A array:
5 5 5 5 5
1 5 5 5 5
1 1 5 5 5
Fortran cho phép bạn xác định các kiểu dữ liệu có nguồn gốc. Kiểu dữ liệu dẫn xuất còn được gọi là cấu trúc và nó có thể bao gồm các đối tượng dữ liệu thuộc các kiểu khác nhau.
Các kiểu dữ liệu có nguồn gốc được sử dụng để biểu diễn một bản ghi. Ví dụ: bạn muốn theo dõi sách của mình trong thư viện, bạn có thể muốn theo dõi các thuộc tính sau của mỗi sách:
- Title
- Author
- Subject
- Mã sách
Xác định kiểu dữ liệu có nguồn gốc
Để xác định một dữ liệu dẫn xuất type, loại và end typecâu lệnh được sử dụng. . Câu lệnh type xác định một kiểu dữ liệu mới, với nhiều hơn một thành viên cho chương trình của bạn. Định dạng của câu lệnh kiểu là:
type type_name
declarations
end type
Đây là cách bạn khai báo cấu trúc Sách -
type Books
character(len = 50) :: title
character(len = 50) :: author
character(len = 150) :: subject
integer :: book_id
end type Books
Truy cập thành viên cấu trúc
Một đối tượng của kiểu dữ liệu dẫn xuất được gọi là cấu trúc.
Cấu trúc kiểu Sách có thể được tạo trong một câu lệnh khai báo kiểu như:
type(Books) :: book1
Các thành phần của cấu trúc có thể được truy cập bằng cách sử dụng ký tự bộ chọn thành phần (%) -
book1%title = "C Programming"
book1%author = "Nuha Ali"
book1%subject = "C Programming Tutorial"
book1%book_id = 6495407
Note that there are no spaces before and after the % symbol.
Thí dụ
Chương trình sau đây minh họa các khái niệm trên:
program deriveDataType
!type declaration
type Books
character(len = 50) :: title
character(len = 50) :: author
character(len = 150) :: subject
integer :: book_id
end type Books
!declaring type variables
type(Books) :: book1
type(Books) :: book2
!accessing the components of the structure
book1%title = "C Programming"
book1%author = "Nuha Ali"
book1%subject = "C Programming Tutorial"
book1%book_id = 6495407
book2%title = "Telecom Billing"
book2%author = "Zara Ali"
book2%subject = "Telecom Billing Tutorial"
book2%book_id = 6495700
!display book info
Print *, book1%title
Print *, book1%author
Print *, book1%subject
Print *, book1%book_id
Print *, book2%title
Print *, book2%author
Print *, book2%subject
Print *, book2%book_id
end program deriveDataType
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
C Programming
Nuha Ali
C Programming Tutorial
6495407
Telecom Billing
Zara Ali
Telecom Billing Tutorial
6495700
Mảng cấu trúc
Bạn cũng có thể tạo mảng có kiểu dẫn xuất -
type(Books), dimension(2) :: list
Các phần tử riêng lẻ của mảng có thể được truy cập dưới dạng:
list(1)%title = "C Programming"
list(1)%author = "Nuha Ali"
list(1)%subject = "C Programming Tutorial"
list(1)%book_id = 6495407
Chương trình sau đây minh họa khái niệm -
program deriveDataType
!type declaration
type Books
character(len = 50) :: title
character(len = 50) :: author
character(len = 150) :: subject
integer :: book_id
end type Books
!declaring array of books
type(Books), dimension(2) :: list
!accessing the components of the structure
list(1)%title = "C Programming"
list(1)%author = "Nuha Ali"
list(1)%subject = "C Programming Tutorial"
list(1)%book_id = 6495407
list(2)%title = "Telecom Billing"
list(2)%author = "Zara Ali"
list(2)%subject = "Telecom Billing Tutorial"
list(2)%book_id = 6495700
!display book info
Print *, list(1)%title
Print *, list(1)%author
Print *, list(1)%subject
Print *, list(1)%book_id
Print *, list(1)%title
Print *, list(2)%author
Print *, list(2)%subject
Print *, list(2)%book_id
end program deriveDataType
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
C Programming
Nuha Ali
C Programming Tutorial
6495407
C Programming
Zara Ali
Telecom Billing Tutorial
6495700
Trong hầu hết các ngôn ngữ lập trình, một biến con trỏ lưu trữ địa chỉ bộ nhớ của một đối tượng. Tuy nhiên, trong Fortran, con trỏ là một đối tượng dữ liệu có nhiều chức năng hơn là chỉ lưu địa chỉ bộ nhớ. Nó chứa nhiều thông tin hơn về một đối tượng cụ thể, như kiểu, thứ hạng, phạm vi và địa chỉ bộ nhớ.
Một con trỏ được liên kết với một mục tiêu bằng cách phân bổ hoặc gán con trỏ.
Khai báo một biến con trỏ
Một biến con trỏ được khai báo với thuộc tính con trỏ.
Các ví dụ sau đây cho thấy khai báo của các biến con trỏ:
integer, pointer :: p1 ! pointer to integer
real, pointer, dimension (:) :: pra ! pointer to 1-dim real array
real, pointer, dimension (:,:) :: pra2 ! pointer to 2-dim real array
Một con trỏ có thể trỏ đến -
Một vùng bộ nhớ được cấp phát động.
Một đối tượng dữ liệu cùng loại với con trỏ, với target thuộc tính.
Phân bổ không gian cho một con trỏ
Các allocatecâu lệnh cho phép bạn cấp phát không gian cho một đối tượng con trỏ. Ví dụ -
program pointerExample
implicit none
integer, pointer :: p1
allocate(p1)
p1 = 1
Print *, p1
p1 = p1 + 4
Print *, p1
end program pointerExample
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
1
5
Bạn nên làm trống không gian lưu trữ được phân bổ bằng cách deallocate tuyên bố khi nó không còn được yêu cầu và tránh tích tụ không gian bộ nhớ không sử dụng và không sử dụng được.
Mục tiêu và Hiệp hội
Mục tiêu là một biến bình thường khác, với không gian dành riêng cho nó. Một biến mục tiêu phải được khai báo vớitarget thuộc tính.
Bạn kết hợp một biến con trỏ với một biến đích bằng cách sử dụng toán tử kết hợp (=>).
Hãy để chúng tôi viết lại ví dụ trước, để chứng minh khái niệm -
program pointerExample
implicit none
integer, pointer :: p1
integer, target :: t1
p1=>t1
p1 = 1
Print *, p1
Print *, t1
p1 = p1 + 4
Print *, p1
Print *, t1
t1 = 8
Print *, p1
Print *, t1
end program pointerExample
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
1
1
5
5
8
8
Một con trỏ có thể là -
- Undefined
- Associated
- Disassociated
Trong chương trình trên, chúng tôi có associatedcon trỏ p1, với mục tiêu t1, sử dụng toán tử =>. Hàm được liên kết, kiểm tra trạng thái liên kết của con trỏ.
Các nullify câu lệnh tách một con trỏ khỏi mục tiêu.
Nullify không làm trống các mục tiêu vì có thể có nhiều hơn một con trỏ trỏ đến cùng một mục tiêu. Tuy nhiên, việc làm trống con trỏ cũng đồng nghĩa với việc vô hiệu hóa.
ví dụ 1
Ví dụ sau minh họa các khái niệm -
program pointerExample
implicit none
integer, pointer :: p1
integer, target :: t1
integer, target :: t2
p1=>t1
p1 = 1
Print *, p1
Print *, t1
p1 = p1 + 4
Print *, p1
Print *, t1
t1 = 8
Print *, p1
Print *, t1
nullify(p1)
Print *, t1
p1=>t2
Print *, associated(p1)
Print*, associated(p1, t1)
Print*, associated(p1, t2)
!what is the value of p1 at present
Print *, p1
Print *, t2
p1 = 10
Print *, p1
Print *, t2
end program pointerExample
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
1
1
5
5
8
8
8
T
F
T
952754640
952754640
10
10
Xin lưu ý rằng mỗi lần bạn chạy mã, địa chỉ bộ nhớ sẽ khác nhau.
Ví dụ 2
program pointerExample
implicit none
integer, pointer :: a, b
integer, target :: t
integer :: n
t = 1
a => t
t = 2
b => t
n = a + b
Print *, a, b, t, n
end program pointerExample
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
2 2 2 4
Cho đến nay, chúng tôi đã thấy rằng chúng tôi có thể đọc dữ liệu từ bàn phím bằng cách sử dụng read * và hiển thị kết quả ra màn hình bằng cách sử dụng print*tương ứng. Hình thức đầu vào-đầu ra này làfree format I / O và nó được gọi là list-directed đầu ra đầu vào.
I / O định dạng miễn phí đơn giản có dạng -
read(*,*) item1, item2, item3...
print *, item1, item2, item3
write(*,*) item1, item2, item3...
Tuy nhiên, I / O được định dạng cho phép bạn linh hoạt hơn trong việc truyền dữ liệu.
Đầu ra đầu vào được định dạng
Đầu ra đầu vào được định dạng có cú pháp như sau:
read fmt, variable_list
print fmt, variable_list
write fmt, variable_list
Ở đâu,
fmt là đặc tả định dạng
danh sách biến là danh sách các biến được đọc từ bàn phím hoặc được viết trên màn hình
Đặc tả định dạng xác định cách hiển thị dữ liệu được định dạng. Nó bao gồm một chuỗi, chứa danh sáchedit descriptors trong dấu ngoặc đơn.
An edit descriptor chỉ định định dạng chính xác, ví dụ: chiều rộng, các chữ số sau dấu thập phân, v.v., trong đó các ký tự và số được hiển thị.
Ví dụ
Print "(f6.3)", pi
Bảng sau đây mô tả các bộ mô tả:
Bộ mô tả | Sự miêu tả | Thí dụ |
---|---|---|
Tôi | Điều này được sử dụng cho đầu ra số nguyên. Điều này có dạng 'rIw.m' trong đó ý nghĩa của r, w và m được đưa ra trong bảng dưới đây. Các giá trị số nguyên chính xác trong trường của chúng. Nếu chiều rộng của trường không đủ lớn để chứa một số nguyên thì trường sẽ được đánh dấu bằng dấu hoa thị. |
print "(3i5)", i, j, k |
F | Điều này được sử dụng cho đầu ra số thực. Điều này có dạng 'rFw.d' trong đó ý nghĩa của r, w và d được đưa ra trong bảng dưới đây. Giá trị thực là chính xác trong trường của chúng. Nếu chiều rộng của trường không đủ lớn để chứa số thực thì trường được đánh dấu bằng các dấu hoa thị. |
print "(f12.3)", pi |
E | Điều này được sử dụng cho đầu ra thực trong ký hiệu hàm mũ. Câu lệnh mô tả 'E' có dạng 'rEw.d' trong đó ý nghĩa của r, w và d được đưa ra trong bảng dưới đây. Giá trị thực là chính xác trong trường của chúng. Nếu chiều rộng của trường không đủ lớn để chứa số thực thì trường được đánh dấu bằng các dấu hoa thị. Xin lưu ý rằng, để in ra một số thực có ba chữ số thập phân, cần có độ rộng trường ít nhất là mười. Một cho dấu của phần định trị, hai cho số 0, bốn cho phần định trị và hai cho chính số mũ. Nói chung, w ≥ d + 7. |
print "(e10.3)", 123456.0 cho '0,123e + 06' |
ES | Điều này được sử dụng cho đầu ra thực (ký hiệu khoa học). Điều này có dạng 'rESw.d' trong đó ý nghĩa của r, w và d được đưa ra trong bảng dưới đây. Bộ mô tả 'E' được mô tả ở trên hơi khác một chút so với 'ký hiệu scienti fi c' truyền thống nổi tiếng. Ký hiệu Scienti fi c có phần định trị trong phạm vi từ 1,0 đến 10,0 không giống như ký hiệu E có phần định trị trong phạm vi 0,1 đến 1,0. Giá trị thực là chính xác trong trường của chúng. Nếu chiều rộng của trường không đủ lớn để chứa số thực thì trường được đánh dấu bằng các dấu hoa thị. Ngoài ra, trường độ rộng phải thỏa mãn biểu thứcw ≥ d + 7 |
print "(es10.3)", 123456.0 cho '1.235e + 05' |
A | Điều này được sử dụng cho đầu ra ký tự. Điều này có dạng 'rAw' trong đó ý nghĩa của r và w được đưa ra trong bảng dưới đây. Các loại ký tự phù hợp với trường của chúng. Nếu độ rộng của trường không đủ lớn để chứa chuỗi ký tự thì trường sẽ được đặt bằng các ký tự 'w' đầu tiên của chuỗi. |
print "(a10)", str |
X | Điều này được sử dụng cho đầu ra không gian. Điều này có dạng 'nX' trong đó 'n' là số khoảng trắng mong muốn. |
print "(5x, a10)", str |
/ | Bộ mô tả dấu gạch chéo - dùng để chèn các dòng trống. Điều này có dạng '/' và buộc đầu ra dữ liệu tiếp theo phải nằm trên một dòng mới. |
print "(/, 5x, a10)", str |
Các ký hiệu sau được sử dụng với các bộ mô tả định dạng:
Sr.No | Biểu tượng & Mô tả |
---|---|
1 | c Số cột |
2 | d Số chữ số ở bên phải của vị trí thập phân cho đầu vào hoặc đầu ra thực |
3 | m Số chữ số tối thiểu được hiển thị |
4 | n Số khoảng trắng cần bỏ qua |
5 | r Số lần lặp lại - số lần sử dụng bộ mô tả hoặc nhóm bộ mô tả |
6 | w Chiều rộng trường - số lượng ký tự để sử dụng cho đầu vào hoặc đầu ra |
ví dụ 1
program printPi
pi = 3.141592653589793238
Print "(f6.3)", pi
Print "(f10.7)", pi
Print "(f20.15)", pi
Print "(e16.4)", pi/100
end program printPi
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
3.142
3.1415927
3.141592741012573
0.3142E-01
Ví dụ 2
program printName
implicit none
character (len = 15) :: first_name
print *,' Enter your first name.'
print *,' Up to 20 characters, please'
read *,first_name
print "(1x,a)",first_name
end program printName
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau: (giả sử người dùng nhập tên Zara)
Enter your first name.
Up to 20 characters, please
Zara
Ví dụ 3
program formattedPrint
implicit none
real :: c = 1.2786456e-9, d = 0.1234567e3
integer :: n = 300789, k = 45, i = 2
character (len=15) :: str="Tutorials Point"
print "(i6)", k
print "(i6.3)", k
print "(3i10)", n, k, i
print "(i10,i3,i5)", n, k, i
print "(a15)",str
print "(f12.3)", d
print "(e12.4)", c
print '(/,3x,"n = ",i6, 3x, "d = ",f7.4)', n, d
end program formattedPrint
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
45
045
300789 45 2
300789 45 2
Tutorials Point
123.457
0.1279E-08
n = 300789 d = *******
Tuyên bố Định dạng
Câu lệnh định dạng cho phép bạn trộn và kết hợp ký tự, số nguyên và đầu ra thực trong một câu lệnh. Ví dụ sau đây chứng minh điều này -
program productDetails
implicit none
character (len = 15) :: name
integer :: id
real :: weight
name = 'Ardupilot'
id = 1
weight = 0.08
print *,' The product details are'
print 100
100 format (7x,'Name:', 7x, 'Id:', 1x, 'Weight:')
print 200, name, id, weight
200 format(1x, a, 2x, i3, 2x, f5.2)
end program productDetails
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
The product details are
Name: Id: Weight:
Ardupilot 1 0.08
Fortran cho phép bạn đọc dữ liệu và ghi dữ liệu vào tệp.
Trong chương trước, bạn đã biết cách đọc dữ liệu từ và ghi dữ liệu vào thiết bị đầu cuối. Trong chương này, bạn sẽ nghiên cứu các chức năng nhập và xuất tệp do Fortran cung cấp.
Bạn có thể đọc và ghi vào một hoặc nhiều tệp. Các câu lệnh OPEN, WRITE, READ và CLOSE cho phép bạn đạt được điều này.
Mở và đóng tệp
Trước khi sử dụng tệp, bạn phải mở tệp. Cácopenlệnh được sử dụng để mở tệp để đọc hoặc ghi. Dạng đơn giản nhất của lệnh là:
open (unit = number, file = "name").
Tuy nhiên, tuyên bố mở có thể có dạng chung:
open (list-of-specifiers)
Bảng sau đây mô tả các từ chỉ định được sử dụng phổ biến nhất:
Sr.No | Chỉ định & Mô tả |
---|---|
1 | [UNIT=] u Số đơn vị u có thể là bất kỳ số nào trong phạm vi 9-99 và nó cho biết tệp, bạn có thể chọn bất kỳ số nào nhưng mọi tệp đang mở trong chương trình phải có một số duy nhất |
2 | IOSTAT= ios Nó là định danh trạng thái I / O và phải là một biến số nguyên. Nếu câu lệnh mở thành công thì giá trị ios được trả về bằng 0 còn giá trị khác không. |
3 | ERR = err Nó là một nhãn mà điều khiển sẽ nhảy vào trong trường hợp có bất kỳ lỗi nào. |
4 | FILE = fname Tên tệp, một chuỗi ký tự. |
5 | STATUS = sta Nó hiển thị trạng thái trước của tệp. Một chuỗi ký tự và có thể có một trong ba giá trị MỚI, CŨ hoặc KHẮC PHỤC. Một tệp tin đầu được tạo và xóa khi đóng hoặc chương trình kết thúc. |
6 | ACCESS = acc Đây là chế độ truy cập tệp. Có thể có một trong hai giá trị, SEQUENTIAL hoặc DIRECT. Mặc định là SEQUENTIAL. |
7 | FORM = frm Nó cung cấp trạng thái định dạng của tệp. Có thể có một trong hai giá trị FORMATTED hoặc UNFORMATTED. Mặc định là UNFORMATTED |
số 8 | RECL = rl Nó chỉ định độ dài của mỗi bản ghi trong tệp truy cập trực tiếp. |
Sau khi tệp đã được mở, nó được truy cập bằng các câu lệnh đọc và ghi. Sau khi hoàn tất, nó sẽ được đóng lại bằng cách sử dụngclose tuyên bố.
Câu lệnh close có cú pháp sau:
close ([UNIT = ]u[,IOSTAT = ios,ERR = err,STATUS = sta])
Xin lưu ý rằng các tham số trong ngoặc là tùy chọn.
Example
Ví dụ này minh họa việc mở một tệp mới để ghi một số dữ liệu vào tệp.
program outputdata
implicit none
real, dimension(100) :: x, y
real, dimension(100) :: p, q
integer :: i
! data
do i=1,100
x(i) = i * 0.1
y(i) = sin(x(i)) * (1-cos(x(i)/3.0))
end do
! output data into a file
open(1, file = 'data1.dat', status = 'new')
do i=1,100
write(1,*) x(i), y(i)
end do
close(1)
end program outputdata
Khi đoạn mã trên được biên dịch và thực thi, nó sẽ tạo ra tệp data1.dat và ghi các giá trị mảng x và y vào đó. Và sau đó đóng tệp.
Đọc từ và ghi vào tệp
Các câu lệnh đọc và ghi tương ứng được sử dụng để đọc từ và ghi vào một tệp tương ứng.
Chúng có cú pháp sau:
read ([UNIT = ]u, [FMT = ]fmt, IOSTAT = ios, ERR = err, END = s)
write([UNIT = ]u, [FMT = ]fmt, IOSTAT = ios, ERR = err, END = s)
Hầu hết các thông số kỹ thuật đã được thảo luận trong bảng trên.
Bộ xác định END = s là một nhãn câu lệnh nơi chương trình nhảy, khi nó đến cuối tệp.
Example
Ví dụ này minh họa việc đọc và ghi vào một tệp.
Trong chương trình này, chúng tôi đọc từ tệp, chúng tôi đã tạo trong ví dụ cuối cùng, data1.dat, và hiển thị nó trên màn hình.
program outputdata
implicit none
real, dimension(100) :: x, y
real, dimension(100) :: p, q
integer :: i
! data
do i = 1,100
x(i) = i * 0.1
y(i) = sin(x(i)) * (1-cos(x(i)/3.0))
end do
! output data into a file
open(1, file = 'data1.dat', status='new')
do i = 1,100
write(1,*) x(i), y(i)
end do
close(1)
! opening the file for reading
open (2, file = 'data1.dat', status = 'old')
do i = 1,100
read(2,*) p(i), q(i)
end do
close(2)
do i = 1,100
write(*,*) p(i), q(i)
end do
end program outputdata
Khi đoạn mã trên được biên dịch và thực thi, nó tạo ra kết quả sau:
0.100000001 5.54589933E-05
0.200000003 4.41325130E-04
0.300000012 1.47636665E-03
0.400000006 3.45637114E-03
0.500000000 6.64328877E-03
0.600000024 1.12552457E-02
0.699999988 1.74576249E-02
0.800000012 2.53552198E-02
0.900000036 3.49861123E-02
1.00000000 4.63171229E-02
1.10000002 5.92407547E-02
1.20000005 7.35742599E-02
1.30000007 8.90605897E-02
1.39999998 0.105371222
1.50000000 0.122110792
1.60000002 0.138823599
1.70000005 0.155002072
1.80000007 0.170096487
1.89999998 0.183526158
2.00000000 0.194692180
2.10000014 0.202990443
2.20000005 0.207826138
2.29999995 0.208628103
2.40000010 0.204863414
2.50000000 0.196052119
2.60000014 0.181780845
2.70000005 0.161716297
2.79999995 0.135617107
2.90000010 0.103344671
3.00000000 6.48725405E-02
3.10000014 2.02930309E-02
3.20000005 -3.01767997E-02
3.29999995 -8.61928314E-02
3.40000010 -0.147283033
3.50000000 -0.212848678
3.60000014 -0.282169819
3.70000005 -0.354410470
3.79999995 -0.428629100
3.90000010 -0.503789663
4.00000000 -0.578774154
4.09999990 -0.652400017
4.20000029 -0.723436713
4.30000019 -0.790623367
4.40000010 -0.852691114
4.50000000 -0.908382416
4.59999990 -0.956472993
4.70000029 -0.995793998
4.80000019 -1.02525222
4.90000010 -1.04385209
5.00000000 -1.05071592
5.09999990 -1.04510069
5.20000029 -1.02641726
5.30000019 -0.994243503
5.40000010 -0.948338211
5.50000000 -0.888650239
5.59999990 -0.815326691
5.70000029 -0.728716135
5.80000019 -0.629372001
5.90000010 -0.518047631
6.00000000 -0.395693362
6.09999990 -0.263447165
6.20000029 -0.122622721
6.30000019 2.53026206E-02
6.40000010 0.178709000
6.50000000 0.335851669
6.59999990 0.494883657
6.70000029 0.653881252
6.80000019 0.810866773
6.90000010 0.963840425
7.00000000 1.11080539
7.09999990 1.24979746
7.20000029 1.37891412
7.30000019 1.49633956
7.40000010 1.60037732
7.50000000 1.68947268
7.59999990 1.76223695
7.70000029 1.81747139
7.80000019 1.85418403
7.90000010 1.87160957
8.00000000 1.86922085
8.10000038 1.84674001
8.19999981 1.80414569
8.30000019 1.74167395
8.40000057 1.65982044
8.50000000 1.55933595
8.60000038 1.44121361
8.69999981 1.30668485
8.80000019 1.15719533
8.90000057 0.994394958
9.00000000 0.820112705
9.10000038 0.636327863
9.19999981 0.445154816
9.30000019 0.248800844
9.40000057 4.95488606E-02
9.50000000 -0.150278628
9.60000038 -0.348357052
9.69999981 -0.542378068
9.80000019 -0.730095863
9.90000057 -0.909344316
10.0000000 -1.07807255
A procedurelà một nhóm các câu lệnh thực hiện một nhiệm vụ được xác định rõ và có thể được gọi từ chương trình của bạn. Thông tin (hoặc dữ liệu) được chuyển tới chương trình gọi, tới thủ tục dưới dạng các đối số.
Có hai loại thủ tục -
- Functions
- Subroutines
Chức năng
Hàm là một thủ tục trả về một số lượng duy nhất. Một hàm không nên sửa đổi các đối số của nó.
Số lượng trả lại được gọi là function value, và nó được biểu thị bằng tên hàm.
Syntax
Cú pháp cho một hàm như sau:
function name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end function [name]
Ví dụ sau minh họa một hàm có tên area_of_circle. Nó tính diện tích của một hình tròn có bán kính r.
program calling_func
real :: a
a = area_of_circle(2.0)
Print *, "The area of a circle with radius 2.0 is"
Print *, a
end program calling_func
! this function computes the area of a circle with radius r
function area_of_circle (r)
! function result
implicit none
! dummy arguments
real :: area_of_circle
! local variables
real :: r
real :: pi
pi = 4 * atan (1.0)
area_of_circle = pi * r**2
end function area_of_circle
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
The area of a circle with radius 2.0 is
12.5663710
Xin lưu ý rằng -
Bạn phải chỉ định implicit none trong cả chương trình chính cũng như thủ tục.
Đối số r trong hàm được gọi là dummy argument.
Lựa chọn kết quả
Nếu bạn muốn giá trị trả về được lưu trữ trong một số tên khác với tên hàm, bạn có thể sử dụng result Lựa chọn.
Bạn có thể chỉ định tên biến trả về là -
function name(arg1, arg2, ....) result (return_var_name)
[declarations, including those for the arguments]
[executable statements]
end function [name]
Chương trình con
Một chương trình con không trả về một giá trị, tuy nhiên nó có thể sửa đổi các đối số của nó.
Syntax
subroutine name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end subroutine [name]
Gọi một chương trình con
Bạn cần gọi một chương trình con bằng cách sử dụng call tuyên bố.
Ví dụ sau minh họa định nghĩa và cách sử dụng hoán đổi chương trình con, thay đổi giá trị của các đối số của nó.
program calling_func
implicit none
real :: a, b
a = 2.0
b = 3.0
Print *, "Before calling swap"
Print *, "a = ", a
Print *, "b = ", b
call swap(a, b)
Print *, "After calling swap"
Print *, "a = ", a
Print *, "b = ", b
end program calling_func
subroutine swap(x, y)
implicit none
real :: x, y, temp
temp = x
x = y
y = temp
end subroutine swap
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000
Xác định ý định của các đối số
Thuộc tính ý định cho phép bạn chỉ định ý định mà các đối số được sử dụng trong thủ tục. Bảng sau cung cấp các giá trị của thuộc tính ý định:
Giá trị | Được dùng như | Giải trình |
---|---|---|
trong | ý định (trong) | Được sử dụng làm giá trị đầu vào, không thay đổi trong hàm |
ngoài | ý định (ra) | Được sử dụng làm giá trị đầu ra, chúng bị ghi đè |
inout | ý định (inout) | Đối số vừa được sử dụng vừa bị ghi đè |
Ví dụ sau thể hiện khái niệm -
program calling_func
implicit none
real :: x, y, z, disc
x = 1.0
y = 5.0
z = 2.0
call intent_example(x, y, z, disc)
Print *, "The value of the discriminant is"
Print *, disc
end program calling_func
subroutine intent_example (a, b, c, d)
implicit none
! dummy arguments
real, intent (in) :: a
real, intent (in) :: b
real, intent (in) :: c
real, intent (out) :: d
d = b * b - 4.0 * a * c
end subroutine intent_example
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
The value of the discriminant is
17.0000000
Thủ tục đệ quy
Đệ quy xảy ra khi một ngôn ngữ lập trình cho phép bạn gọi một hàm bên trong cùng một hàm. Nó được gọi là lời gọi đệ quy của hàm.
Khi một thủ tục gọi chính nó, trực tiếp hoặc gián tiếp, được gọi là một thủ tục đệ quy. Bạn nên khai báo loại thủ tục này bằng cách đứng trước từrecursive trước khi tuyên bố của nó.
Khi một hàm được sử dụng đệ quy, result tùy chọn phải được sử dụng.
Sau đây là một ví dụ, tính giai thừa cho một số nhất định bằng thủ tục đệ quy:
program calling_func
implicit none
integer :: i, f
i = 15
Print *, "The value of factorial 15 is"
f = myfactorial(15)
Print *, f
end program calling_func
! computes the factorial of n (n!)
recursive function myfactorial (n) result (fac)
! function result
implicit none
! dummy arguments
integer :: fac
integer, intent (in) :: n
select case (n)
case (0:1)
fac = 1
case default
fac = n * myfactorial (n-1)
end select
end function myfactorial
Thủ tục nội bộ
Khi một thủ tục được chứa trong một chương trình, nó được gọi là thủ tục nội bộ của chương trình. Cú pháp để chứa một thủ tục nội bộ như sau:
program program_name
implicit none
! type declaration statements
! executable statements
. . .
contains
! internal procedures
. . .
end program program_name
Ví dụ sau thể hiện khái niệm -
program mainprog
implicit none
real :: a, b
a = 2.0
b = 3.0
Print *, "Before calling swap"
Print *, "a = ", a
Print *, "b = ", b
call swap(a, b)
Print *, "After calling swap"
Print *, "a = ", a
Print *, "b = ", b
contains
subroutine swap(x, y)
real :: x, y, temp
temp = x
x = y
y = temp
end subroutine swap
end program mainprog
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000
Một mô-đun giống như một gói nơi bạn có thể giữ các chức năng và chương trình con của mình, trong trường hợp bạn đang viết một chương trình rất lớn, hoặc các chức năng hoặc chương trình con của bạn có thể được sử dụng trong nhiều chương trình.
Mô-đun cung cấp cho bạn một cách để tách chương trình của bạn giữa nhiều tệp.
Mô-đun được sử dụng cho -
Đóng gói chương trình con, dữ liệu và khối giao diện.
Xác định dữ liệu toàn cục có thể được sử dụng bởi nhiều hơn một quy trình.
Khai báo các biến có thể được tạo sẵn trong bất kỳ quy trình nào bạn chọn.
Nhập hoàn toàn một mô-đun để sử dụng vào một chương trình hoặc chương trình con khác.
Cú pháp của một mô-đun
Một mô-đun bao gồm hai phần -
- một phần đặc điểm kỹ thuật cho khai báo câu lệnh
- một phần chứa các định nghĩa chương trình con và hàm
Dạng tổng quát của mô-đun là -
module name
[statement declarations]
[contains [subroutine and function definitions] ]
end module [name]
Sử dụng một Mô-đun vào Chương trình của bạn
Bạn có thể kết hợp một mô-đun trong một chương trình hoặc chương trình con bằng câu lệnh sử dụng -
use name
Xin lưu ý rằng
Bạn có thể thêm bao nhiêu mô-đun nếu cần, mỗi mô-đun sẽ nằm trong các tệp riêng biệt và được biên dịch riêng.
Một mô-đun có thể được sử dụng trong nhiều chương trình khác nhau.
Một mô-đun có thể được sử dụng nhiều lần trong cùng một chương trình.
Các biến được khai báo trong phần đặc tả mô-đun, là chung cho mô-đun.
Các biến được khai báo trong một mô-đun trở thành các biến toàn cục trong bất kỳ chương trình hoặc quy trình nào mà mô-đun được sử dụng.
Câu lệnh sử dụng có thể xuất hiện trong chương trình chính hoặc bất kỳ chương trình con hoặc mô-đun nào khác sử dụng các thủ tục hoặc biến được khai báo trong một mô-đun cụ thể.
Thí dụ
Ví dụ sau thể hiện khái niệm -
module constants
implicit none
real, parameter :: pi = 3.1415926536
real, parameter :: e = 2.7182818285
contains
subroutine show_consts()
print*, "Pi = ", pi
print*, "e = ", e
end subroutine show_consts
end module constants
program module_example
use constants
implicit none
real :: x, ePowerx, area, radius
x = 2.0
radius = 7.0
ePowerx = e ** x
area = pi * radius**2
call show_consts()
print*, "e raised to the power of 2.0 = ", ePowerx
print*, "Area of a circle with radius 7.0 = ", area
end program module_example
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Pi = 3.14159274
e = 2.71828175
e raised to the power of 2.0 = 7.38905573
Area of a circle with radius 7.0 = 153.938049
Khả năng truy cập của các biến và chương trình con trong một mô-đun
Theo mặc định, tất cả các biến và chương trình con trong một mô-đun được cung cấp cho chương trình đang sử dụng mã mô-đun, bằng cách use tuyên bố.
Tuy nhiên, bạn có thể kiểm soát khả năng truy cập của mã mô-đun bằng cách sử dụng private và publicthuộc tính. Khi bạn khai báo một số biến hoặc chương trình con là private, nó không có sẵn bên ngoài mô-đun.
Thí dụ
Ví dụ sau minh họa khái niệm -
Trong ví dụ trước, chúng tôi có hai biến mô-đun, e và pi. Hãy để chúng tôi đặt chúng ở chế độ riêng tư và quan sát đầu ra -
module constants
implicit none
real, parameter,private :: pi = 3.1415926536
real, parameter, private :: e = 2.7182818285
contains
subroutine show_consts()
print*, "Pi = ", pi
print*, "e = ", e
end subroutine show_consts
end module constants
program module_example
use constants
implicit none
real :: x, ePowerx, area, radius
x = 2.0
radius = 7.0
ePowerx = e ** x
area = pi * radius**2
call show_consts()
print*, "e raised to the power of 2.0 = ", ePowerx
print*, "Area of a circle with radius 7.0 = ", area
end program module_example
Khi bạn biên dịch và thực thi chương trình trên, nó sẽ đưa ra thông báo lỗi sau:
ePowerx = e ** x
1
Error: Symbol 'e' at (1) has no IMPLICIT type
main.f95:19.13:
area = pi * radius**2
1
Error: Symbol 'pi' at (1) has no IMPLICIT type
Từ e và pi, cả hai đều được khai báo là private, chương trình module_example không thể truy cập các biến này nữa.
Tuy nhiên, các chương trình con của mô-đun khác có thể truy cập chúng -
module constants
implicit none
real, parameter,private :: pi = 3.1415926536
real, parameter, private :: e = 2.7182818285
contains
subroutine show_consts()
print*, "Pi = ", pi
print*, "e = ", e
end subroutine show_consts
function ePowerx(x)result(ePx)
implicit none
real::x
real::ePx
ePx = e ** x
end function ePowerx
function areaCircle(r)result(a)
implicit none
real::r
real::a
a = pi * r**2
end function areaCircle
end module constants
program module_example
use constants
implicit none
call show_consts()
Print*, "e raised to the power of 2.0 = ", ePowerx(2.0)
print*, "Area of a circle with radius 7.0 = ", areaCircle(7.0)
end program module_example
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
Pi = 3.14159274
e = 2.71828175
e raised to the power of 2.0 = 7.38905573
Area of a circle with radius 7.0 = 153.938049
Các chức năng nội tại là một số chức năng phổ biến và quan trọng được cung cấp như một phần của ngôn ngữ Fortran. Chúng ta đã thảo luận về một số hàm này trong các chương Mảng, Ký tự và Chuỗi.
Các chức năng nội tại có thể được phân loại là -
- Hàm số
- Các hàm toán học
- Các chức năng truy vấn số
- Chức năng thao tác dấu chấm động
- Chức năng thao tác bit
- Chức năng nhân vật
- Chức năng loại
- Các chức năng logic
- Hàm mảng.
Chúng ta đã thảo luận về các hàm mảng trong chương Mảng. Trong phần sau, chúng tôi cung cấp mô tả ngắn gọn về tất cả các chức năng này từ các danh mục khác.
Trong cột tên hàm,
- A đại diện cho bất kỳ loại biến số nào
- R đại diện cho một biến số thực hoặc số nguyên
- X và Y đại diện cho các biến thực
- Z đại diện cho biến phức tạp
- W đại diện cho biến thực hoặc biến phức
Hàm số
Sr.No | Mô tả chức năng |
---|---|
1 | ABS (A) Nó trả về giá trị tuyệt đối của A |
2 | AIMAG (Z) Nó trả về phần ảo của một số phức Z |
3 | AINT (A [, KIND]) Nó cắt bớt một phần phân số của A về 0, trả về một số nguyên, thực. |
4 | ANINT (A [, KIND]) Nó trả về một giá trị thực, số nguyên hoặc số nguyên gần nhất. |
5 | CEILING (A [, KIND]) Nó trả về số nguyên nhỏ nhất lớn hơn hoặc bằng số A. |
6 | CMPLX (X [, Y, KIND]) Nó chuyển đổi các biến thực X và Y thành một số phức X + iY; nếu Y vắng mặt, 0 được sử dụng. |
7 | CONJG (Z) Nó trả về liên hợp phức của bất kỳ số phức Z nào. |
số 8 | DBLE (A) Nó chuyển đổi A thành một số thực chính xác gấp đôi. |
9 | DIM (X, Y) Nó trả về chênh lệch dương của X và Y. |
10 | DPROD (X, Y) Nó trả về tích thực chính xác gấp đôi của X và Y. |
11 | FLOOR (A [, KIND]) Nó cung cấp số nguyên lớn nhất nhỏ hơn hoặc bằng số A. |
12 | INT (A [, KIND]) Nó chuyển đổi một số (thực hoặc số nguyên) thành số nguyên, cắt bớt phần thực về 0. |
13 | MAX (A1, A2 [, A3,...]) Nó trả về giá trị lớn nhất từ các đối số, tất cả đều có cùng kiểu. |
14 | MIN (A1, A2 [, A3,...]) Nó trả về giá trị nhỏ nhất từ các đối số, tất cả đều có cùng kiểu. |
15 | MOD (A, P) Nó trả về phần còn lại của A khi chia cho P, cả hai đối số đều có cùng kiểu (A-INT (A / P) * P) |
16 | MODULO (A, P) Nó trả về A modulo P: (A-FLOOR (A / P) * P) |
17 | NINT (A [, KIND]) Nó trả về số nguyên gần nhất của số A |
18 | REAL (A [, KIND]) Nó chuyển đổi thành loại thực |
19 | SIGN (A, B) Nó trả về giá trị tuyệt đối của A nhân với dấu của P. Về cơ bản, nó chuyển dấu của B sang A. |
Thí dụ
program numericFunctions
implicit none
! define constants
! define variables
real :: a, b
complex :: z
! values for a, b
a = 15.2345
b = -20.7689
write(*,*) 'abs(a): ',abs(a),' abs(b): ',abs(b)
write(*,*) 'aint(a): ',aint(a),' aint(b): ',aint(b)
write(*,*) 'ceiling(a): ',ceiling(a),' ceiling(b): ',ceiling(b)
write(*,*) 'floor(a): ',floor(a),' floor(b): ',floor(b)
z = cmplx(a, b)
write(*,*) 'z: ',z
end program numericFunctions
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
abs(a): 15.2344999 abs(b): 20.7688999
aint(a): 15.0000000 aint(b): -20.0000000
ceiling(a): 16 ceiling(b): -20
floor(a): 15 floor(b): -21
z: (15.2344999, -20.7688999)
Các hàm toán học
Sr.No | Mô tả chức năng |
---|---|
1 | ACOS (X) Nó trả về cosin nghịch đảo trong khoảng (0, π), tính bằng radian. |
2 | ASIN (X) Nó trả về sin nghịch đảo trong khoảng (-π / 2, π / 2), tính bằng radian. |
3 | ATAN (X) Nó trả về tiếp tuyến nghịch đảo trong khoảng (-π / 2, π / 2), tính bằng radian. |
4 | ATAN2 (Y, X) Nó trả về tiếp tuyến nghịch đảo trong khoảng (-π, π), tính bằng radian. |
5 | COS (X) Nó trả về cosine của đối số tính bằng radian. |
6 | COSH (X) Nó trả về cosin hyperbol của đối số tính bằng radian. |
7 | EXP (X) Nó trả về giá trị theo cấp số nhân của X. |
số 8 | LOG (X) Nó trả về giá trị logarit tự nhiên của X. |
9 | LOG10 (X) Nó trả về giá trị logarit chung (cơ số 10) của X. |
10 | SIN (X) Nó trả về sin của đối số tính bằng radian. |
11 | SINH (X) Nó trả về sin hyperbol của đối số tính bằng radian. |
12 | SQRT (X) Nó trả về căn bậc hai của X. |
13 | TAN (X) Nó trả về tiếp tuyến của đối số tính bằng radian. |
14 | TANH (X) Nó trả về tiếp tuyến hyperbol của đối số tính bằng radian. |
Thí dụ
Chương trình sau đây tính toán vị trí nằm ngang và thẳng đứng x và y tương ứng của một viên đạn sau một thời gian, t -
Trong đó, x = ut cos a và y = ut sin a - g t2 / 2
program projectileMotion
implicit none
! define constants
real, parameter :: g = 9.8
real, parameter :: pi = 3.1415927
!define variables
real :: a, t, u, x, y
!values for a, t, and u
a = 45.0
t = 20.0
u = 10.0
! convert angle to radians
a = a * pi / 180.0
x = u * cos(a) * t
y = u * sin(a) * t - 0.5 * g * t * t
write(*,*) 'x: ',x,' y: ',y
end program projectileMotion
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
x: 141.421356 y: -1818.57861
Các chức năng truy vấn số
Các hàm này hoạt động với một mô hình số học số nguyên và dấu phẩy động nhất định. Các hàm trả về thuộc tính của các số cùng loại với biến X, có thể là số thực và trong một số trường hợp là số nguyên.
Sr.No | Mô tả chức năng |
---|---|
1 | DIGITS (X) Nó trả về số chữ số có nghĩa của mô hình. |
2 | EPSILON (X) Nó trả về con số gần như không đáng kể so với một. Nói cách khác, nó trả về giá trị nhỏ nhất sao cho REAL (1,0, KIND (X)) + EPSILON (X) không bằng REAL (1,0, KIND (X)). |
3 | HUGE (X) Nó trả về số lượng lớn nhất của mô hình |
4 | MAXEXPONENT (X) Nó trả về số mũ lớn nhất của mô hình |
5 | MINEXPONENT (X) Nó trả về số mũ tối thiểu của mô hình |
6 | PRECISION (X) Nó trả về độ chính xác thập phân |
7 | RADIX (X) Nó trả về cơ sở của mô hình |
số 8 | RANGE (X) Nó trả về phạm vi số mũ thập phân |
9 | TINY (X) Nó trả về số dương nhỏ nhất của mô hình |
Chức năng thao tác dấu chấm động
Sr.No | Mô tả chức năng |
---|---|
1 | EXPONENT (X) Nó trả về phần lũy thừa của một số kiểu máy |
2 | FRACTION (X) Nó trả về phần phân số của một số |
3 | NEAREST (X, S) Nó trả về số bộ xử lý khác nhau gần nhất theo hướng nhất định |
4 | RRSPACING (X) Nó trả về nghịch đảo của khoảng cách tương đối của các số kiểu máy gần số nhất định |
5 | SCALE (X, I) Nó nhân một số thực với cơ số của nó thành một lũy thừa |
6 | SET_EXPONENT (X, I) nó trả về phần lũy thừa của một số |
7 | SPACING (X) Nó trả về khoảng cách tuyệt đối của các số kiểu máy gần số nhất định |
Chức năng thao tác bit
Sr.No | Mô tả chức năng |
---|---|
1 | BIT_SIZE (I) Nó trả về số bit của mô hình |
2 | BTEST (I, POS) Kiểm tra bit |
3 | IAND (I, J) Logic AND |
4 | IBCLR (I, POS) Xóa bit |
5 | IBITS (I, POS, LEN) Trích xuất bit |
6 | IBSET (I, POS) Đặt bit |
7 | IEOR (I, J) Độc quyền HOẶC |
số 8 | IOR (I, J) Bao gồm HOẶC |
9 | ISHFT (I, SHIFT) Sự thay đổi lôgic |
10 | ISHFTC (I, SHIFT [, SIZE]) Chuyển dịch tròn |
11 | NOT (I) Bổ sung logic |
Chức năng nhân vật
Sr.No | Mô tả chức năng |
---|---|
1 | ACHAR (I) Nó trả về ký tự thứ I trong chuỗi đối chiếu ASCII. |
2 | ADJUSTL (STRING) Nó điều chỉnh chuỗi còn lại bằng cách loại bỏ bất kỳ khoảng trống nào ở đầu và chèn các khoảng trống ở cuối |
3 | ADJUSTR (STRING) Nó điều chỉnh chuỗi ngay bằng cách loại bỏ các khoảng trống ở cuối và chèn các khoảng trống ở đầu. |
4 | CHAR (I [, KIND]) Nó trả về ký tự thứ I trong trình tự đối chiếu đặc điểm của máy |
5 | IACHAR (C) Nó trả về vị trí của ký tự trong chuỗi đối chiếu ASCII. |
6 | ICHAR (C) Nó trả về vị trí của ký tự trong trình tự đối chiếu cụ thể của máy (bộ xử lý). |
7 | INDEX (STRING, SUBSTRING [, BACK]) Nó trả về vị trí bắt đầu ở ngoài cùng bên trái (ngoài cùng bên phải nếu BACK là .TRUE.) Của SUBSTRING trong STRING. |
số 8 | LEN (STRING) Nó trả về độ dài của một chuỗi. |
9 | LEN_TRIM (STRING) Nó trả về độ dài của một chuỗi mà không có ký tự trống theo sau. |
10 | LGE (STRING_A, STRING_B) Về mặt ngữ nghĩa lớn hơn hoặc bằng |
11 | LGT (STRING_A, STRING_B) Về mặt ngữ nghĩa lớn hơn |
12 | LLE (STRING_A, STRING_B) Về mặt ngữ nghĩa nhỏ hơn hoặc bằng |
13 | LLT (STRING_A, STRING_B) Về mặt ngữ nghĩa ít hơn |
14 | REPEAT (STRING, NCOPIES) Nối lặp lại |
15 | SCAN (STRING, SET [, BACK]) Nó trả về chỉ mục của ký tự ngoài cùng bên trái (ngoài cùng bên phải nếu BACK là .TRUE.) Của STRING thuộc về SET hoặc 0 nếu không thuộc về. |
16 | TRIM (STRING) Xóa các ký tự trống ở cuối |
17 | VERIFY (STRING, SET [, BACK]) Xác minh tập hợp các ký tự trong một chuỗi |
Chức năng loại
Sr.No | Mô tả chức năng |
---|---|
1 | KIND (X) Nó trả về giá trị tham số kiểu loại. |
2 | SELECTED_INT_KIND (R) Nó trả về loại tham số kiểu cho phạm vi số mũ cụ thể. |
3 | SELECTED_REAL_KIND ([P, R]) Giá trị thông số loại thực, độ chính xác và phạm vi đã cho |
Chức năng logic
Sr.No | Mô tả chức năng |
---|---|
1 | LOGICAL (L [, KIND]) Chuyển đổi giữa các đối tượng kiểu logic với các tham số kiểu khác nhau |
Chúng tôi đã thảo luận rằng, trong các phiên bản Fortran cũ hơn, có hai real loại: loại thực mặc định và double precision kiểu.
Tuy nhiên, Fortran 90/95 cung cấp nhiều quyền kiểm soát hơn đối với độ chính xác của các kiểu dữ liệu số nguyên và thực thông qua kind cụ thể.
Thuộc tính loại
Các loại số khác nhau được lưu trữ khác nhau bên trong máy tính. Cáckindthuộc tính cho phép bạn chỉ định cách một số được lưu trữ bên trong. Ví dụ,
real, kind = 2 :: a, b, c
real, kind = 4 :: e, f, g
integer, kind = 2 :: i, j, k
integer, kind = 3 :: l, m, n
Trong phần khai báo trên, các biến thực e, f và g có độ chính xác cao hơn các biến thực a, b và c. Các biến số nguyên l, m và n, có thể lưu trữ các giá trị lớn hơn và có nhiều chữ số để lưu trữ hơn các biến số nguyên i, j và k. Mặc dù điều này là phụ thuộc vào máy móc.
Thí dụ
program kindSpecifier
implicit none
real(kind = 4) :: a, b, c
real(kind = 8) :: e, f, g
integer(kind = 2) :: i, j, k
integer(kind = 4) :: l, m, n
integer :: kind_a, kind_i, kind_e, kind_l
kind_a = kind(a)
kind_i = kind(i)
kind_e = kind(e)
kind_l = kind(l)
print *,'default kind for real is', kind_a
print *,'default kind for int is', kind_i
print *,'extended kind for real is', kind_e
print *,'default kind for int is', kind_l
end program kindSpecifier
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
default kind for real is 4
default kind for int is 2
extended kind for real is 8
default kind for int is 4
Yêu cầu kích thước của các biến
Có một số chức năng nội tại cho phép bạn thẩm vấn kích thước của các con số.
Ví dụ, bit_size(i)hàm nội tại chỉ định số lượng bit được sử dụng để lưu trữ. Đối với số thực,precision(x) hàm nội tại, trả về số chữ số thập phân của độ chính xác, trong khi range(x) hàm nội tại trả về phạm vi thập phân của số mũ.
Thí dụ
program getSize
implicit none
real (kind = 4) :: a
real (kind = 8) :: b
integer (kind = 2) :: i
integer (kind = 4) :: j
print *,'precision of real(4) =', precision(a)
print *,'precision of real(8) =', precision(b)
print *,'range of real(4) =', range(a)
print *,'range of real(8) =', range(b)
print *,'maximum exponent of real(4) =' , maxexponent(a)
print *,'maximum exponent of real(8) =' , maxexponent(b)
print *,'minimum exponent of real(4) =' , minexponent(a)
print *,'minimum exponent of real(8) =' , minexponent(b)
print *,'bits in integer(2) =' , bit_size(i)
print *,'bits in integer(4) =' , bit_size(j)
end program getSize
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
precision of real(4) = 6
precision of real(8) = 15
range of real(4) = 37
range of real(8) = 307
maximum exponent of real(4) = 128
maximum exponent of real(8) = 1024
minimum exponent of real(4) = -125
minimum exponent of real(8) = -1021
bits in integer(2) = 16
bits in integer(4) = 32
Đạt được giá trị tử tế
Fortran cung cấp thêm hai hàm nội tại để lấy giá trị loại cho độ chính xác cần thiết của số nguyên và số thực -
- select_int_kind (r)
- select_real_kind ([p, r])
Hàm select_real_kind trả về một số nguyên là giá trị tham số kiểu loại cần thiết cho một độ chính xác thập phân nhất định p và phạm vi số mũ thập phân r. Độ chính xác thập phân là số chữ số có nghĩa và phạm vi số mũ thập phân chỉ định số nhỏ nhất và lớn nhất có thể biểu diễn. Do đó, phạm vi là từ 10-r đến 10 + r.
Ví dụ: select_real_kind (p = 10, r = 99) trả về giá trị loại cần thiết để có độ chính xác 10 chữ số thập phân và phạm vi ít nhất từ 10-99 đến 10 + 99.
Thí dụ
program getKind
implicit none
integer:: i
i = selected_real_kind (p = 10, r = 99)
print *,'selected_real_kind (p = 10, r = 99)', i
end program getKind
Khi bạn biên dịch và thực thi chương trình trên, nó tạo ra kết quả sau:
selected_real_kind (p = 10, r = 99) 8
Có nhiều công cụ và thư viện Fortran khác nhau. Một số là miễn phí và một số là dịch vụ trả phí.
Sau đây là một số thư viện miễn phí -
- RANDLIB, bộ tạo số ngẫu nhiên và phân phối thống kê
- BLAS
- EISPACK
- Hướng dẫn GAMS – NIST về Phần mềm Toán học Có sẵn
- Một số thống kê và các quy trình khác từ NIST
- LAPACK
- LINPACK
- MINPACK
- MUDPACK
- Thư viện Toán học NCAR
- Bộ sưu tập Netlib gồm phần mềm toán học, giấy tờ và cơ sở dữ liệu.
- ODEPACK
- ODERPACK, một tập hợp các quy trình để xếp hạng và đặt hàng.
- Expokit cho ma trận tính toán theo cấp số nhân
- SLATEC
- SPECFUN
- STARPAC
- Thư viện thống kê StatLib
- TOMS
- Sắp xếp và hợp nhất các chuỗi
Các thư viện sau đây không miễn phí -
- Thư viện số NAG Fortran
- Thư viện IMSL Visual Numerics
- Công thức số
Phong cách lập trình là tuân theo một số quy tắc trong khi phát triển chương trình. Các phương pháp hay này truyền tải các giá trị như khả năng đọc và tính rõ ràng vào chương trình của bạn.
Một chương trình tốt phải có các đặc điểm sau:
- Readability
- Cấu trúc logic phù hợp
- Ghi chú và nhận xét tự giải thích
Ví dụ, nếu bạn đưa ra nhận xét như sau, nó sẽ không giúp ích được gì nhiều -
! loop from 1 to 10
do i = 1,10
Tuy nhiên, nếu bạn đang tính toán hệ số nhị thức và cần vòng lặp này cho nCr thì một nhận xét như thế này sẽ hữu ích -
! loop to calculate nCr
do i = 1,10
Các khối mã thụt lề để làm rõ các cấp mã khác nhau.
Tự kiểm tra mã để đảm bảo sẽ không có lỗi số như chia cho không, căn bậc hai của một số thực âm hoặc lôgarit của một số thực âm.
Bao gồm các mã đảm bảo các biến không nhận các giá trị bất hợp pháp hoặc nằm ngoài phạm vi, tức là xác thực đầu vào.
Không đặt séc ở nơi không cần thiết và làm chậm quá trình thực thi. Ví dụ -
real :: x
x = sin(y) + 1.0
if (x >= 0.0) then
z = sqrt(x)
end if
- Mã được viết rõ ràng bằng cách sử dụng các thuật toán thích hợp.
- Tách các biểu thức dài bằng cách sử dụng dấu tiếp nối '&'.
- Tạo tên biến có ý nghĩa.
Một công cụ gỡ lỗi được sử dụng để tìm kiếm lỗi trong chương trình.
Một chương trình gỡ lỗi bước qua mã và cho phép bạn kiểm tra các giá trị trong các biến và các đối tượng dữ liệu khác trong quá trình thực thi chương trình.
Nó tải mã nguồn và bạn phải chạy chương trình trong trình gỡ lỗi. Trình gỡ lỗi gỡ lỗi chương trình bằng cách -
- Đặt các điểm ngắt,
- Bước qua mã nguồn,
- Đặt điểm đồng hồ.
Các điểm ngắt chỉ định nơi chương trình sẽ dừng lại, cụ thể là sau một dòng mã quan trọng. Chương trình thực thi sau khi các biến được kiểm tra tại một điểm ngắt.
Các chương trình gỡ lỗi cũng kiểm tra từng dòng mã nguồn.
Điểm theo dõi là những điểm cần kiểm tra giá trị của một số biến, đặc biệt là sau một thao tác đọc hoặc ghi.
Trình gỡ lỗi gdb
Trình gỡ lỗi gdb, trình gỡ lỗi GNU đi kèm với hệ điều hành Linux. Đối với hệ thống cửa sổ X, gdb đi kèm với giao diện đồ họa và chương trình được đặt tên là xxgdb.
Bảng sau cung cấp một số lệnh trong gdb:
Chỉ huy | Mục đích |
---|---|
phá vỡ | Đặt điểm ngắt |
chạy | Bắt đầu thực hiện |
tiếp | Tiếp tục thực hiện |
kế tiếp | Chỉ thực thi dòng mã nguồn tiếp theo mà không cần bước vào bất kỳ lệnh gọi hàm nào |
bươc | Thực thi dòng tiếp theo của mã nguồn bằng cách bước vào một hàm trong trường hợp gọi hàm. |
Trình gỡ lỗi dbx
Có một trình gỡ lỗi khác, trình gỡ lỗi dbx, dành cho Linux.
Bảng sau cung cấp một số lệnh trong dbx:
Chỉ huy | Mục đích |
---|---|
dừng lại [var] | Đặt điểm ngắt khi giá trị của biến var thay đổi. |
dừng lại ở [proc] | Nó dừng thực thi khi một quy trình thủ tục được nhập |
dừng lại ở [dòng] | Nó thiết lập một điểm ngắt tại một dòng được chỉ định. |
chạy | Bắt đầu thực hiện. |
tiếp | Tiếp tục thực hiện. |
kế tiếp | Chỉ thực thi dòng mã nguồn tiếp theo mà không cần thực hiện bất kỳ lệnh gọi hàm nào. |
bươc | Thực thi dòng tiếp theo của mã nguồn bằng cách bước vào một hàm trong trường hợp gọi hàm. |