![]() |
博学的黄瓜 · 问:哪些情况可以提取住房公积金?是否可以通过 ...· 1 年前 · |
![]() |
温暖的煎饼 · 中央和地方预算报告中的名词解释· 1 年前 · |
![]() |
憨厚的水煮肉 · 电视剧《大秦帝国2》_影音娱乐_新浪网· 1 年前 · |
![]() |
逼格高的跑步鞋 · 杭州雷峰塔:拥有西湖古老而又神秘的传说,是杭 ...· 1 年前 · |
![]() |
奔跑的黄瓜 · 旧世界专区_Old ...· 1 年前 · |
转载自 https://iowiki.com/fortran/ ,在此基础上做了一些补充。
Fortran,源自公式翻译系统,是一种通用的命令式编程语言。 它用于数字和科学计算。
Fortran最初由IBM在20世纪50年代开发用于科学和工程应用。 Fortran统治了这个编程领域很长一段时间,并且因为高性能计算而变得非常流行。
它支持 -
G95是GNU Fortran多架构编译器,用于在Windows中设置Fortran。 Windows版本在Windows下使用MingW模拟unix环境。 安装程序会处理此问题并自动将g95添加到Windows PATH变量中。
你可以从 here 获得稳定版的G95
在安装过程中,如果选择“RECOMMENDED”选项, g95 将自动添加到PATH变量中。 这意味着您只需打开一个新的命令提示符窗口并键入“g95”即可打开编译器。 找到下面的一些基本命令来帮助您入门。
Sr.No 命令和描述-c Compile only, do not run the linker.
-o Specify the name of the output file, either an object file or the executable.
可以一次指定多个源文件和目标文件。 Fortran文件由以“.f”,“.F”,“。for”,“.FOR”,“。f90”,“.F90”,“。f95”,“.F95”,“。”结尾的名称表示。 f03“和”.F03“。 可以指定多个源文件。 也可以指定目标文件,并将其链接以形成可执行文件。
在linux中设置Fortran
这里使用ubuntu,安装如下:
sudo apt install gfortran-10
Fortran - Basic Syntax
Fortran程序由一组程序单元组成,如主程序,模块和外部子程序或过程。
每个程序包含一个主程序,可能包含也可能不包含其他程序单元。 主程序的语法如下 -
program program_name
implicit none
! type declaration statements
! executable statements
end program program_name
Fortran中的一个简单程序
让我们编写一个程序,添加两个数字并打印结果 -
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
编译并执行上述程序时,会产生以下结果 -
The total is 27.0000000
请注意 -
所有Fortran程序都以关键字program开头,以关键字end program,后跟end program,名称。
implicit none语句允许编译器检查是否正确声明了所有变量类型。 您必须始终在每个程序的开头使用implicit none 。
Fortran中的注释以感叹号(!)开头,因为编译器会忽略此后的所有字符(字符串除外)。
print *命令在屏幕上显示数据。
压缩代码行是保持程序可读性的好方法。
Fortran允许使用大写和小写字母。 除字符串文字外,Fortran不区分大小写。
Basics
Fortran的basic character set包含 -
字母A ... Z和a ... z
数字0 ... 9
下划线(_)字符
特殊字符=:+空白 - * /()[] ,. $'! “%&; <>?
Tokens由基本字符集中的字符组成。 令牌可以是关键字,标识符,常量,字符串文字或符号。
程序语句由令牌组成。
识别 Identifier
标识符是用于标识变量,过程或任何其他用户定义项的名称。 Fortran中的名称必须遵循以下规则 -
它不能超过31个字符。
它必须由字母数字字符(字母表中的所有字母,数字0到9)和下划线(_)组成。
名称的第一个字符必须是字母。
名称不区分大小写
关键字 (Keywords)
关键字是为语言保留的特殊单词。 这些保留字不能用作标识符或名称。
下表列出了Fortran关键字 -
非I/O关键字
请注意, huge()函数给出了特定整数数据类型可以保存的最大数字。 您还可以使用kind说明符指定字节数。 以下示例演示了这一点 -
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
编译并执行上述程序时,会产生以下结果 -
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647
真实的类型
它存储浮点数,例如2.0,3.1415,-100.876等。
传统上有两种不同的实际类型,默认的real类型和double precision类型。
但是,Fortran 90/95通过kind说明符提供了对实数和整数数据类型精度的更多控制,我们将在有关数字的章节中进行研究。
以下示例显示了实际数据类型的使用 -
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
编译并执行上述程序时,会产生以下结果 -
0.666666687
这用于存储复数。 复数有两部分,实部和虚部。 两个连续的数字存储单元存储这两个部分。
例如,复数(3.0,-5.0)等于3.0 - 5.0i
我们将在Numbers章节中更详细地讨论复杂类型。
只有两个逻辑值: .true. 和.false.
字符类型存储字符和字符串。 字符串的长度可以由len说明符指定。 如果未指定长度,则为1。
For example,
character (len = 40) :: name
name = “Zara Ali”
表达式name(1:4)将给出子串“Zara”。
较旧版本的Fortran允许一种称为隐式类型的功能,即您不必在使用前声明变量。 如果未声明变量,则其名称的第一个字母将确定其类型。
以i,j,k,l,m或n开头的变量名称被认为是整数变量,其他变量是实变量。 但是,您必须声明所有变量,因为它是良好的编程习惯。 为此你用声明开始你的程序 -
implicit none
此语句将关闭隐式类型。
Fortran - Variables
变量只不过是我们的程序可以操作的存储区域的名称。 每个变量都应该有一个特定的类型,它决定了变量内存的大小和布局; 可存储在该内存中的值范围; 以及可以应用于变量的操作集。
变量的名称可以由字母,数字和下划线字符组成。 Fortran中的名称必须遵循以下规则 -
它不能超过31个字符。
它必须由字母数字字符(字母表中的所有字母,数字0到9)和下划线(_)组成。
名称的第一个字符必须是字母。
名称不区分大小写。
基于前一章中解释的基本类型,以下是变量类型 -
Sr.No
类型和描述
您还可以使用内部函数cmplx,将值赋给复杂变量 -
cx = cmplx (1.0/2.0, -7.0) ! cx = 0.5 – 7.0i
cx = cmplx (x, y) ! cx = x + yi
例子 (Example)
以下示例演示了屏幕上的变量声明,分配和显示 -
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 IOWIKI"
cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
Print *, total
Print *, average
Print *, cx
Print *, done
Print *, message
end program variableTesting
编译并执行上述代码时,会产生以下结果 -
20000
1666.67004
(3.00000000, 5.00000000 )
A big Hello from IOWIKI
Fortran - Constants
常量是指程序在执行期间无法更改的固定值。 这些固定值也称为literals 。
常量可以是任何基本数据类型,如整数常量,浮点常量,字符常量,复数常量或字符串文字。 只有两个逻辑常量: .true. 和.false.
常量被视为常规变量,除了它们的值在定义后无法修改。
命名常量和文字
常量有两种类型 -
文字常量具有值,但没有名称。
例如,以下是文字常量 -
命名常量具有值和名称。
命名常量应在程序或过程的开头声明,就像变量类型声明一样,指示其名称和类型。 使用parameter属性声明命名常量。 例如,
real, parameter :: pi = 3.1415927
例子 (Example)
以下程序计算重力作用下垂直运动引起的位移。
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
编译并执行上述代码时,会产生以下结果 -
Time = 5.00000000
Displacement = 127.374992
Fortran - Operators
运算符是一个符号,告诉编译器执行特定的数学或逻辑操作。 Fortran提供以下类型的运算符 -
算术运算符
关系运算符
逻辑运算符
让我们一个一个地看看所有这些类型的运算符。
算术运算符 (Arithmetic Operators)
下表显示了Fortran支持的所有算术运算符。 假设变量A保持5,变量B保持3然后 -
逻辑运算符 (Logical Operators)
Fortran中的逻辑运算符仅适用于逻辑值.true。 和.false。
下表显示了Fortran支持的所有逻辑运算符。 假设变量A保持.true。 变量B保持.false。 那么 -
Fortran中的运算符优先级
运算符优先级确定表达式中的术语分组。 这会影响表达式的计算方式。 某些运算符的优先级高于其他运算符; 例如,乘法运算符的优先级高于加法运算符。
例如,x = 7 + 3 * 2; 这里,x被赋值为13,而不是20,因为operator *的优先级高于+,所以它首先乘以3 * 2然后加到7中。
此处,具有最高优先级的运算符显示在表的顶部,具有最低优先级的运算符显示在底部。 在表达式中,将首先评估更高优先级的运算符。
Fortran - Decisions
决策结构要求程序员指定一个或多个要由程序评估或测试的条件,以及要执行的语句,如果条件被确定为真,并且可选地,如果是,则执行其他语句条件被确定为假。
以下是大多数编程语言中常见决策结构的一般形式 -
Fortran提供以下类型的决策构造。
Sr.No
声明和说明
If… then...else constructif… then语句后面可以跟一个可选的else statement,该else statement,在逻辑表达式为false时执行。
if ... else if ... else Statementif语句构造可以有一个或多个可选的else-if构造。 当if条件失败时,紧接着执行else-if 。 当else-if也失败时,执行其后继else-if语句(如果有的话),依此类推。
嵌套if构造您可以在另一个if或else if语句中使用if或else if语句。
选择案例构造select case语句允许根据值列表测试变量的相等性。
嵌套的选择案例构造您可以在另一个select case语句中使用一个select case语句。
Fortran - Loops
当您需要多次执行代码块时,可能会出现这种情况。 通常,语句按顺序执行:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。
编程语言提供各种控制结构,允许更复杂的执行路径。
循环语句允许我们多次执行语句或语句组,以下是大多数编程语言中循环语句的一般形式 -
Fortran提供以下类型的循环结构来处理循环需求。 单击以下链接以检查其详细信息。
Sr.No
循环类型和描述
请注意, huge()函数给出了特定整数数据类型可以保存的最大数字。 您还可以使用kind说明符指定字节数。 以下示例演示了这一点 -
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
编译并执行上述程序时,会产生以下结果 -
32767
2147483647
9223372036854775807
170141183460469231731687303715884105727
2147483647
真实的类型
它存储浮点数,例如2.0,3.1415,-100.876等。
传统上有两种不同的real类型:默认的真实类型和double precision类型。
但是,Fortran 90/95通过kind说明符提供了对实数和整数数据类型精度的更多控制,我们将在稍后研究。
以下示例显示了实际数据类型的使用 -
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
编译并执行上述程序时,会产生以下结果 -
0.666666687
这用于存储复数。 复数有两部分:实部和虚部。 两个连续的数字存储单元存储这两个部分。
例如,复数(3.0,-5.0)等于3.0 - 5.0i
泛型函数cmplx()创建一个复数。 它产生的结果是,无论输入参数的类型如何,其实部和虚部都是单精度的。
program createComplex
implicit none
integer :: i = 10
real :: x = 5.17
print *, cmplx(i, x)
end program createComplex
编译并执行上述程序时,会产生以下结果 -
(10.0000000, 5.17000008)
以下程序演示了复数运算 -
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
编译并执行上述程序时,会产生以下结果 -
(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)
数字的范围,精度和大小
整数范围,精度和浮点数的大小取决于分配给特定数据类型的位数。
下表显示整数的位数和范围 -
Fortran - Characters
Fortran语言可以将字符视为单个字符或连续字符串。
字符可以是从基本字符集中取出的任何符号,即字母,十进制数字,下划线和21个特殊字符。
字符常量是固定值字符串。
内在数据类型character存储字符和字符串。 字符串的长度可以由len说明符指定。 如果未指定长度,则为1.您可以按位置引用字符串中的单个字符; 最左边的字符位于第1位。
声明字符类型数据与其他变量相同 -
type-specifier :: variable_name
character :: reply, sex
你可以分配一个值,如,
reply = ‘N’
sex = ‘F’
以下示例演示了字符数据类型的声明和使用 -
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
编译并执行上述程序时,会产生以下结果 -
Here is Mr. Rowan Atkinson
A big hello from Mr. Bean
连接运算符//连接字符。
以下示例演示了这一点 -
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
编译并执行上述程序时,会产生以下结果 -
Here is Mr.Rowan Atkinson
A big hello from Mr.Bean
Some 字符函数
下表显示了一些常用的字符函数以及描述 -
Sr.No
scan(string, chars)对于“chars”中包含的任何字符的第一次出现,它从左到右搜索“string”(除非back = .true。)。 它返回一个给出该字符位置的整数,如果没有找到“chars”中的字符,则返回零。
verify(string, chars)它从左到右扫描“字符串”(除非back = .true。)第一次出现“chars”中没有包含的任何字符。 它返回一个给出该字符位置的整数,如果只找到“chars”中的字符,则返回零
adjustl(string)它左对齐“字符串”中包含的字符
adjustr(string)它正确地证明了“字符串”中包含的字符
len_trim(string)它返回一个等于“string”(len(string))长度的整数减去尾随空格的数量
repeat(string,ncopy)它返回一个长度等于“ncopy”的字符串乘以“string”的长度,并包含“ncopy”连接的“string”副本
例子1 (Example 1)
此示例显示了index函数的使用 -
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
编译并执行上述程序时,会产生以下结果 -
The word character found at position 25
in text : The intrinsic data type character stores characters and strings.
例子2 (Example 2)
此示例演示了trim功能的使用 -
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
编译并执行上述程序时,会产生以下结果 -
Here isMr. Rowan Atkinson
Here isMr. Rowan Atkinson
例子3 (Example 3)
这个例子演示了achar功能的使用 -
program testingChars
implicit none
character:: ch
integer:: i
do i = 65, 90
ch = achar(i)
print*, i, ' ', ch
end do
end program testingChars
编译并执行上述程序时,会产生以下结果 -
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
检查字符的词法顺序
以下函数确定字符的词汇顺序 -
Sr.No
Fortran - Strings
Fortran语言可以将字符视为单个字符或连续字符串。
字符串的长度可以只有一个字符,或者甚至可以是零长度。 在Fortran中,字符常量在一对双引号或单引号之间给出。
内在数据类型character存储字符和字符串。 字符串的长度可以由len specifier 。 如果未指定长度,则为1.您可以按位置引用字符串中的单个字符; 最左边的字符位于第1位。
字符串声明
声明字符串与其他变量相同 -
type-specifier :: variable_name
Character(len = 20) :: firstname, surname
你可以分配一个值,如,
character (len = 40) :: name
name = “Zara Ali”
以下示例演示了字符数据类型的声明和使用 -
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
编译并执行上述程序时,会产生以下结果 -
Here is Mr. Rowan Atkinson
A big hello from Mr. Bean
字符串连接 (String Concatenation)
连接运算符//连接字符串。
以下示例演示了这一点 -
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
编译并执行上述程序时,会产生以下结果 -
Here is Mr. Rowan Atkinson
A big hello from Mr. Bean
提取子字符串
在Fortran中,您可以通过索引字符串从字符串中提取子字符串,在一对括号中给出子字符串的开始和结束索引。 这称为范围说明符。
以下示例显示如何从字符串'hello world'中提取子字符串'world' -
program subString
character(len = 11)::hello
hello = "Hello World"
print*, hello(7:11)
end program subString
编译并执行上述程序时,会产生以下结果 -
World
例子 (Example)
以下示例使用date_and_time函数来提供日期和时间字符串。 我们使用范围说明符分别提取年份,日期,月份,小时,分钟和第二个信息。
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
当您编译并执行上述程序时,它会提供详细的日期和时间信息 -
Date String: 20140803
Year: 2014
Month: 08
Day: 03
Time String: 075835.466
Hour: 07
Minute: 58
Second: 35.466
修剪字符串
trim函数接受一个字符串,并在删除所有尾随空白后返回输入字符串。
例子 (Example)
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
编译并执行上述程序时,会产生以下结果 -
Susanne Rizwan , the beautiful dancer from the east!
Susanne Rizwan, the beautiful dancer from the east!
字符串的左右调整
函数adjustl接受一个字符串并通过删除前导空格并将它们作为尾随空格附加来返回它。
函数adjustr接受一个字符串并通过删除尾随空白并将它们作为前导空格附加来返回它。
例子 (Example)
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
编译并执行上述程序时,会产生以下结果 -
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
在字符串中搜索子字符串
index函数接受两个字符串并检查第二个字符串是否是第一个字符串的子字符串。 如果第二个参数是第一个参数的子字符串,则它返回一个整数,该整数是第一个字符串中第二个字符串的起始索引,否则返回零。
例子 (Example)
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'
print *, 'test is found at index: ', index(myString, testString)
end if
end program hello
编译并执行上述程序时,会产生以下结果 -
test is found at index: 11
Fortran - Arrays
数组可以存储相同类型的固定大小的顺序元素集合。 数组用于存储数据集合,但将数组视为相同类型的变量集合通常更有用。
所有阵列都包含连续的内存位置。 最低地址对应于第一个元素,最高地址对应于最后一个元素。
Numbers(1)
Numbers(2)
Numbers(3)
Numbers(4)
real, dimension(5) :: numbers
通过指定其下标来引用数组的各个元素。 数组的第一个元素的下标为1。 数组编号包含五个实数变量 - 数字(1),数字(2),数字(3),数字(4)和数字(5)。
要创建一个名为matrix的5 x 5二维整数数组,你可以写 -
integer, dimension (5,5) :: matrix
您还可以声明一个具有一些显式下限的数组,例如 -
real, dimension(2:6) :: numbers
integer, dimension (-3:2,0:4) :: matrix
您可以为单个成员分配值,例如,
numbers(1) = 2.0
或者,你可以使用循环,
do i =1,5
numbers(i) = i * 2.0
end do
一维数组元素可以使用称为数组构造函数的简写符号直接赋值,如,
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 '/'
例子 (Example)
以下示例演示了上面讨论的概念。
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
编译并执行上述代码时,会产生以下结果 -
2.00000000
4.00000000
6.00000000
8.00000000
10.0000000
1.50000000
3.20000005
4.50000000
0.899999976
7.19999981
一些阵列相关术语
下表给出了一些与数组相关的术语 -
在上面的示例中,子例程fillArray和printArray只能使用维度为5的数组调用。但是,要编写可用于任何大小的数组的子例程,可以使用以下技术重写它 -
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
请注意,程序使用size函数来获取数组的大小。
编译并执行上述代码时,会产生以下结果 -
到目前为止,我们已经引用了整个数组,Fortran提供了一种使用单个语句引用多个元素或数组的一部分的简单方法。
要访问数组部分,您需要提供该部分的下限和上限,以及所有维度的步幅(增量)。 这种表示法称为subscript triplet:
array ([lower]:[upper][:stride], ...)
如果没有提到下限和上限,则默认为您声明的范围,并且步幅值默认为1。
以下示例演示了该概念 -
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
编译并执行上述代码时,会产生以下结果 -
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
Array Intrinsic Functions
Fortran 90/95提供了几种内在程序。 它们可以分为7类。
Vector and matrix multiplication
Reduction
Inquiry
Construction
Reshape
Manipulation
Location
Fortran - Dynamic Arrays
dynamic array是一个数组,其大小在编译时是未知的,但在执行时将是已知的。
使用属性allocatable声明动态数组。
real, dimension (:,:), allocatable :: darray
但是,为了将内存分配给这样的数组,你必须提到数组的等级,即维度,你可以使用allocate函数。
allocate ( darray(s1,s2) )
使用数组后,在程序中,应使用deallocate函数释放创建的内存
deallocate (darray)
例子 (Example)
以下示例演示了上面讨论的概念。
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
编译并执行上述代码时,会产生以下结果 -
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
Use of Data 语句
data语句可用于初始化多个阵列,或用于阵列段初始化。
数据语句的语法是 -
data variable/list/...
例子 (Example)
以下示例演示了该概念 -
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
编译并执行上述代码时,会产生以下结果 -
The A array:
The B array:
1 1 1
2 2 2
3 3 3
The C array:
Use of Where 语句
where语句允许您在表达式中使用数组的某些元素,具体取决于某些逻辑条件的结果。 如果给定条件为真,它允许在元素上执行表达式。
例子 (Example)
以下示例演示了该概念 -
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
编译并执行上述代码时,会产生以下结果 -
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 - Derived Data Types
Fortran允许您定义派生数据类型。 派生数据类型也称为结构,它可以由不同类型的数据对象组成。
派生数据类型用于表示记录。 例如,您想要在图书馆中跟踪您的图书,您可能希望跟踪每本图书的以下属性 -
Title
Author
Subject
Book ID
定义派生数据类型
要定义派生数据type ,请使用类型和end type语句。 。 type语句定义一个新的数据类型,为您的程序提供多个成员。 类型语句的格式是这样的 -
type type_name
declarations
end type
以下是您声明Book结构的方式 -
type Books
character(len = 50) :: title
character(len = 50) :: author
character(len = 150) :: subject
integer :: book_id
end type Books
访问结构成员 (Accessing Structure Members)
派生数据类型的对象称为结构。
可以在类型声明语句中创建Books类型的结构,如 -
type(Books) :: book1
可以使用组件选择器字符(%)访问结构的组件 -
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.
例子 (Example)
以下程序说明了上述概念 -
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
编译并执行上述代码时,会产生以下结果 -
C Programming
Nuha Ali
C Programming Tutorial
6495407
Telecom Billing
Zara Ali
Telecom Billing Tutorial
6495700
您还可以创建派生类型的数组 -
type(Books), dimension(2) :: list
阵列的各个元素可以访问为 -
list(1)%title = "C Programming"
list(1)%author = "Nuha Ali"
list(1)%subject = "C Programming Tutorial"
list(1)%book_id = 6495407
以下计划说明了这一概念 -
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
编译并执行上述代码时,会产生以下结果 -
C Programming
Nuha Ali
C Programming Tutorial
6495407
C Programming
Zara Ali
Telecom Billing Tutorial
6495700
Fortran - Pointers
在大多数编程语言中,指针变量存储对象的内存地址。 但是,在Fortran中,指针是一种数据对象,它具有比仅存储内存地址更多的功能。 它包含有关特定对象的更多信息,如类型,等级,范围和内存地址。
指针通过分配或指针分配与目标相关联。
声明指针变量
使用pointer属性声明指针变量。
以下示例显示了指针变量的声明 -
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
指针可以指向 -
动态分配内存的区域。
与指针具有相同类型的数据对象,具有target属性。
为指针分配空间
allocate语句允许您为指针对象分配空间。 例如 -
program pointerExample
implicit none
integer, pointer :: p1
allocate(p1)
p1 = 1
Print *, p1
p1 = p1 + 4
Print *, p1
end program pointerExample
编译并执行上述代码时,会产生以下结果 -
当不再需要时,应该通过deallocate语句清空分配的存储空间,并避免累积未使用和不可用的内存空间。
目标和协会
目标是另一个正常变量,为它留出空间。 必须使用target属性声明目标变量。
使用关联运算符(=>)将指针变量与目标变量相关联。
让我们重写前面的例子,来证明这个概念 -
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
编译并执行上述代码时,会产生以下结果 -
指针可以是 -
Undefined
Associated
Disassociated
在上面的程序中,我们使用=“运算符将指针p1与目标t1 associated 。 相关函数测试指针的关联状态。
nullify语句将指针与目标解除关联。
Nullify不会清空目标,因为可能有多个指针指向同一目标。 但是,清空指针也意味着无效。
例子1 (Example 1)
以下示例演示了这些概念 -
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
编译并执行上述代码时,会产生以下结果 -
952754640
952754640
请注意,每次运行代码时,内存地址都会有所不同。
例子2 (Example 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
编译并执行上述代码时,会产生以下结果 -
2 2 2 4
Fortran - Basic Input Output
到目前为止,我们已经看到我们可以使用read *语句从键盘读取数据,并分别使用print*语句将输出显示到屏幕。 这种形式的输入输出是free format I/O,它被称为list-directed输入输出。
免费格式的简单I/O具有以下形式 -
read(*,*) item1, item2, item3...
print *, item1, item2, item3
write(*,*) item1, item2, item3...
但是,格式化的I/O为您提供了更大的数据传输灵活性。
格式化输入输出
格式化输入输出的语法如下 -
read fmt, variable_list
print fmt, variable_list
write fmt, variable_list
Where,
fmt是格式规范
变量列表是要从键盘读取或写在屏幕上的变量列表
格式规范定义了格式化数据的显示方式。 它由一个字符串组成,其中包含括号中的edit descriptors列表。
edit descriptor指定确切的格式,例如,宽度,小数点后的数字等,其中显示字符和数字。
例如 (For example)
Print "(f6.3)", pi
下表描述了描述符 -
这用于整数输出。 这采用'rIw.m'形式,其中r,w和m的含义在下表中给出。 整数值在他们的领域是正确的。 如果现场宽度不足以容纳整数,那么该字段将填充星号。
print“(3i5)”,i,j,k
这用于实数输出。 这采用'rFw.d'形式,其中r,w和d的含义在下表中给出。 真正的价值观在他们的领域是正确的。 如果现场宽度不足以容纳实数,那么该字段将填充星号。
打印“(f12.3)”,pi
这用于指数表示法的实际输出。 'E'描述符语句采用'rEw.d'形式,其中r,w和d的含义在下表中给出。 真正的价值观在他们的领域是正确的。 如果现场宽度不足以容纳实数,那么该字段将填充星号。请注意,要打印出带有三位小数的实数,需要至少十位的字段宽度。 一个用于尾数的符号,两个用于零,四个用于尾数,两个用于指数本身。 通常,w≥d+ 7。
print“(e10.3)”,123456.0给出'0.123e + 06'
这用于实际输出(科学记数法)。 这采用'rESw.d'形式,其中r,w和d的含义在下表中给出。 上面描述的'E'描述符与传统众所周知的'scienti fi c符号'略有不同。 科学符号的尾数在1.0到10.0的范围内,而E描述符的尾数在0.1到1.0的范围内。 真正的价值观在他们的领域是正确的。 如果现场宽度不足以容纳实数,那么该字段将填充星号。 这里,宽度场必须满足表达式w≥d+ 7
print“(es10.3)”,123456.0给出'1.235e + 05'
这用于字符输出。 这采用'rAw'形式,其中r和w的含义在下表中给出。 字符类型在他们的领域是正确的。 如果字段宽度不足以容纳字符串,那么字段将填充字符串的第一个“w”字符。
print“(a10)”,str
这用于空间输出。 采用'nX'形式,其中'n'是所需空格的数量。
print“(5x,a10)”,str
斜杠描述符 - 用于插入空行。 采用“/”形式并强制下一个数据输出在新行上。
print“(/,5x,a10)”,str
以下符号与格式描述符一起使用 -
Sr.No
符号和描述
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
编译并执行上述代码时,会产生以下结果:(假设用户输入名称Zara)
Enter your first name.
Up to 20 characters, please
例子3 (Example 3)
program formattedPrint
implicit none
real :: c = 1.2786456e-9, d = 0.1234567e3
integer :: n = 300789, k = 45, i = 2
character (len=15) :: str="IOWIKI"
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
编译并执行上述代码时,会产生以下结果 -
300789 45 2
300789 45 2
IOWIKI
123.457
0.1279E-08
n = 300789 d = *******
Format 语句
format语句允许您在一个语句中混合和匹配字符,整数和实际输出。 以下示例演示了这一点 -
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
编译并执行上述代码时,会产生以下结果 -
The product details are
Name: Id: Weight:
Ardupilot 1 0.08
Fortran - File Input Output
Fortran允许您从文件中读取数据并将数据写入文件。
在上一章中,您已经了解了如何从终端读取数据和向终端写入数据。 在本章中,您将学习Fortran提供的文件输入和输出功能。
您可以读取和写入一个或多个文件。 OPEN,WRITE,READ和CLOSE语句允许您实现此目的。
打开和关闭文件 (Opening and Closing Files)
在使用文件之前,您必须打开该文件。 open命令用于打开文件进行读写。 最简单的命令形式是 -
open (unit = number, file = "name").
但是,公开声明可能有一般形式 -
open (list-of-specifiers)
下表描述了最常用的说明符 -
Sr.No
说明和描述
打开文件后,将通过读写语句访问它。 完成后,应使用close语句关闭它。
close语句具有以下语法 -
close ([UNIT = ]u[,IOSTAT = ios,ERR = err,STATUS = sta])
请注意括号中的参数是可选的。
Example
此示例演示如何打开新文件以将某些数据写入文件。
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
编译并执行上述代码时,它会创建文件data1.dat并将x和y数组值写入其中。 然后关闭文件。
读取和写入文件
read和write语句分别用于分别读取和写入文件。
它们具有以下语法 -
read ([UNIT = ]u, [FMT = ]fmt, IOSTAT = ios, ERR = err, END = s)
write([UNIT = ]u, [FMT = ]fmt, IOSTAT = ios, ERR = err, END = s)
大多数说明符已在上表中讨论过。
END = s说明符是一个语句标签,程序在到达文件结尾时跳转。
Example
此示例演示如何读取和写入文件。
在这个程序中,我们从文件中读取,我们在最后一个例子中创建了data1.dat,并在屏幕上显示它。
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
编译并执行上述代码时,会产生以下结果 -
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
Fortran - Procedures
procedure是一组执行定义明确的任务的语句,可以从您的程序中调用。 信息(或数据)作为参数传递给调用程序和过程。
有两种类型的程序 -
Functions
Subroutines
Function
函数是返回单个数量的过程。 函数不应修改其参数。
返回的数量称为function value ,它由函数名称表示。
Syntax
函数的语法如下 -
function name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end function [name]
以下示例演示了一个名为area_of_circle的函数。 它计算半径为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
编译并执行上述程序时,会产生以下结果 -
The area of a circle with radius 2.0 is
12.5663710
请注意 -
您必须在主程序和过程中指定implicit none 。
被调用函数中的参数r称为dummy argument 。
如果希望将返回值存储在函数名以外的其他名称中,则可以使用result选项。
您可以将返回变量名称指定为 -
function name(arg1, arg2, ....) result (return_var_name)
[declarations, including those for the arguments]
[executable statements]
end function [name]
12345
子程序 (Subroutine)
子例程不返回值,但可以修改其参数。
Syntax
subroutine name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end subroutine [name]
12345
调用子程序
您需要使用call语句调用子例程。
以下示例演示了子例程交换的定义和用法,它更改了其参数的值。
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
123456789101112131415161718192021
编译并执行上述程序时,会产生以下结果 -
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000
1234567
指定参数的意图
intent属性允许您指定在过程中使用参数的意图。 下表提供了intent属性的值 -
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
1234567891011121314151617181920
编译并执行上述程序时,会产生以下结果 -
The value of the discriminant is
17.0000000
当编程语言允许您在同一函数内调用函数时,就会发生递归。 它被称为函数的递归调用。
当一个过程直接或间接地调用自身时,称为递归过程。 您应该在声明之前在recursive一词之前声明这种类型的过程。
递归使用函数时,必须使用result选项。
以下是一个示例,它使用递归过程计算给定数字的阶乘 -
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
1234567891011121314151617181920212223
当程序包含在程序中时,它被称为程序的内部过程。 包含内部过程的语法如下 -
program program_name
implicit none
! type declaration statements
! executable statements
. . .
contains
! internal procedures
. . .
end program program_name
12345678910
以下示例演示了该概念 -
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
123456789101112131415161718192021
编译并执行上述程序时,会产生以下结果 -
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000
1234567
Fortran - Modules
模块就像一个包,你可以保存你的函数和子程序,以防你编写一个非常大的程序,或者你的函数或子程序可以在多个程序中使用。
模块为您提供了一种在多个文件之间拆分程序的方法。
模块用于 -
打包子程序,数据和接口块。
定义可由多个例程使用的全局数据。
声明可以在您选择的任何例程中使用的变量。
将模块完全导入到另一个程序或子程序中以供使用。
模块的语法
一个模块由两部分组成 -
声明声明的规范部分
a包含子程序和函数定义的部分
模块的一般形式是 -
module name
[statement declarations]
[contains [subroutine and function definitions] ]
end module [name]
12345
将模块用于您的程序
您可以通过use语句将模块合并到程序或子例程中 -
use name
您可以根据需要添加任意数量的模块,每个模块将位于单独的文件中并单独编译。
模块可用于各种不同的程序。
模块可以在同一程序中多次使用。
在模块规范部分中声明的变量对模块是全局的。
模块中声明的变量在使用模块的任何程序或例程中成为全局变量。
use语句可以出现在主程序或使用特定模块中声明的例程或变量的任何其他子例程或模块中。
例子 (Example)
以下示例演示了该概念 -
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
1234567891011121314151617181920212223
编译并执行上述程序时,会产生以下结果 -
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
12345
模块中变量和子程序的可访问性
默认情况下,模块中的所有变量和子例程都可以通过use语句使用模块代码的程序。
但是,您可以使用private和public属性控制模块代码的可访问性。 当您将某个变量或子例程声明为私有时,它在模块外部不可用。
例子 (Example)
以下示例说明了这一概念 -
在前面的示例中,我们有两个模块变量e和pi. 让我们将它们设为私有并观察输出 -
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
1234567891011121314151617181920212223