Fortran教程
Fortran语言来自公式翻译系统,是一种通用的,命令式编程语言。它可用于数字和科学计算。Fortran语言最初是由IBM公司在20世纪50年代的科学和工程应用开发。 FORTRAN统治这个规划计算面积很长一段时间,因其高性能计算能力而很受欢迎。
它支持:
- 数值分析和科学计算
- 结构化程序设计
- 数组编程
- 模块化编程
- 泛型编程
- 超级计算机高性能计算
- 面向对象编程
- 并行编程
- 计算机系统之间的可移植性的合理程度
关于Fortran语言事实
- Fortran语言是由一个团队,由约翰·巴克斯带头于1957年在IBM创建。
- 最初将编写所有投资所使用的名称,但是目前的标准和实现只需要第一个字母要大写。
- Fortran语言表示的公式转换器。
- 最初是为科学计算开发的,它必须为字符串,需要通用编程等结构的支持非常有限。
- 后来延伸和发展使其成为一个高层次的编程语言,可移植性好度。
- 原来的版本,Fortran语言I,II和III 现在认为是过时的。
- 最早的版本仍然在使用 Fortran IV和Fortran 66。
- 最常用的版本,现在用的是:Fortran 77,Fortran 90,和Fortran95。
- Fortran 77 添加字符串作为一个独立的类型。
- Fortran 90 加入形形色色的线程,并直接数组处理。
Fortran语言环境设置 - Fortran教程
在Windows上设置Fortran语言环境
G95是GNU Fortran语言多架构的编译器,用于建立Fortran语言在Windows中。 Windows版本的模拟使用MingW平台下的Windows UNIX环境。安装完成这个功能,并自动添加G95到Windows PATH变量。
可以从G95的稳定版这里得到:
如何使用G95
在安装过程中,G95会自动添加到PATH变量中,如果选择“RECOMMENDED”选项。这意味着,可以简单地打开一个新的命令提示符窗口,输入“G95”,弹出的编译器。找到一些基本的命令,我们现在就开始吧。
命令 | 描述 |
g95 –c hello.f90 | 编译hello.f 90到目标文件命名为hello.o |
g95 hello.f90 | 编译hello.f 90并链接到生成可执行的a.out 文件 |
g95 -c h1.f90 h2.f90 h3.f90 | 编译多个源文件。如果一切顺利的话,目标文件h1.o,h2.o和h3.o创建 |
g95 -o hello h1.f90 h2.f90 h3.f90 | 编译多个源文件并将它们链接在一起,命名为'hello'的可执行文件 |
G95的命令行选项:
-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" and ".F03".“。对于”结尾表示多个源文件可以被指定。目标文件可以被指定为良好,将被链接以形成一个可执行文件。
Fortran基本语法 - Fortran教程
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程序start关键字程序和end关键字结束程序,然后是该程序的名称。
- 隐无语句允许编译器检查所有的变量类型是正确声明。必须始终使用无隐在每个程序的开始。
- 在Fortran语言注释开始使用感叹号(!),因为在这之后的所有字符(除字符串)被编译器忽略。
- print*命令在屏幕上显示数据。
- 代码行缩进,是保持一个程序读取一个很好的做法。
- Fortran语言允许大写和小写字母。 Fortran语言是区分大小写的,除了字符串常量。
基础知识
Fortran语言的基本字符集包括:
- 字符包括 A ... Z 和 a ... z
- 数字 0 ... 9
- 下划线(_)字符
- 特殊字符 = : + 空格- * / ( ) [ ] , . $ ' ! " % & ; < > ?
令牌Tokens基本字符集中的字符。令牌可以是一个关键字,标识符,常量,字符串文字或符号。
程序语句作出标记。
标识符
一个标识符是用于标识一个变量,过程或任何其它用户定义的项目的名称。在Fortran语言中名称必须遵循以下规则:
- 它不能超过31个字符长。
- 它必须由字母数字字符(字母的所有字母,以及数字0到9)和下划线(_)。
- 名称第一个字符必须是字母。
- 名称是区分大小写
关键字
关键字是特殊的词语,这些是语言预留的。这些保留字不能用作标识符或名称。
下表列出了Fortran关键字:
非I/O相关关键字 | ||||
allocatable | allocate | assign | assignment | block data |
call | case | character | common | complex |
contains | continue | cycle | data | deallocate |
default | do | double precision | else | else if |
elsewhere | end block data | end do | end function | end if |
end interface | end module | end program | end select | end subroutine |
end type | end where | entry | equivalence | exit |
external | function | go to | if | implicit |
in | inout | integer | intent | interface |
intrinsic | kind | len | logical | module |
namelist | nullify | only | operator | optional |
out | parameter | pause | pointer | private |
program | public | real | recursive | result |
return | save | select case | stop | subroutine |
target | then | type | type() | use |
Where | While | |||
I/O相关的关键字 | ||||
--- | ||||
backspace | close | endfile | format | inquire |
open | read | rewind | Write |
Fortran数据类型 - Fortran教程
Fortran语言提供了五种内在数据类型,但是,也可以得到自己的数据类型。这五个固有的类型有:
- 整型
- 实型
- 复杂类型
- 逻辑类型
- 字符类型
整型
整数类型只能容纳整数值。下面的示例中提取,可以在通常为4字节整数保存最大值:
program testingInt
implicit none
integer :: largeval
print *, huge(largeval)
end program testingInt
当编译并执行上述程序也将产生以下结果:
2147483647
需要注意的是huge()函数,可以通过特定的整数数据类型可以保持的最大数目。还可以指定使用的字节数。下面的例子说明了这一点:
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等
传统上有两种不同的实际类型,默认实型和双精度型。
然而,Fortran语言90/95提供了更多的控制权实数和整数数据类型,通过种类说明,我们将在对数的章节研究精度。
下面的例子展示了如何使用实数类型:
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
0
复杂类型
这被用于存储复数。一个复杂的数字有两部分,实数部分和虚数部分。两个连续的数字存储单元存储两个部分。
例如,该复数(3.0,-5.0)等于3.0 - 5.0i
我们将更详细地讨论复杂类型,在数字章节。
逻辑类型
只有两个逻辑值:.true. 和.false
字符类型
字符类型存储字符和字符串。字符串的长度可以通过len个符来指定。如果没有指定长度,它是1。
例如,
character (len=40) :: name
name = “Zara Ali”
表达式name(1:4)将得到的子串“Zara”。
隐式类型
Fortran语言的旧版本允许一个叫做隐式类型,也就是说,不必在使用前声明变量的功能。如果一个变量没有声明,则其名称为第一个字母,将确定其类型。
其中i的变量名以 i, j, k, l, m, 或 n 开始,被认为是为整数变量,其余都是实型变量。但是,必须声明所有的变量,因为它是良好的编程习惯。开始程序如下:
implicit none
这条语句将关闭隐式类型。
Fortran变量 - Fortran教程
变量是只不过给定到存储区域,我们的程序可以操作的名称。每个变量都应该具有特定的类型,它决定了大小和变量的存储器的布局; 存储器内存储的值的范围; 和设置操作,可以变化应用。
一个变量名可以由字母,数字和下划线字符。在Fortran语言的名称必须遵循以下规则:
- 它不能超过31个字符长度。
- 它必须由字母数字字符(字母的所有字母,以及数字0到9)和下划线(_)。
- 名称第一个字符必须是字母。
- 名称是区分大小写的。
基于基本类型前一章介绍,以下是该变量的类型:
类型 | 描述 |
整型 | 它只能容纳整数值 |
实型 | 它存储浮点数 |
复数 | 它被用于存储复数. |
逻辑 | 它存储逻辑布尔值 |
字符 | 它存储的字符或字符串。 |
变量声明
变量是在一个程序(或子程序)的类型声明语句的开头声明。
变量声明语法如下:
type-specifier :: variable_name
例如,
integer :: total
real :: average
complex :: cx
logical :: done
character(len=80) :: message ! a string of 80 characters
稍后,可以将值分配给这些变量一样,
total = 20000
average = 1666.67
done = .true.
message = “A big Hello from Tutorials Point”
cx = (3.0, 5.0) ! cx = 3.0 + 5.0i
也可以使用内部函数cmplx,把值赋给一个复杂的变量:
cx = cmplx (1.0/2.0, -7.0) ! cx = 0.5 – 7.0i
cx = cmplx (x, y) ! cx = x + yi
例子
下面的例子演示了变量声明,赋值显示在屏幕上:
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 Yiibai"
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 )
T
A big Hello from Tutorials Yiibai
Fortran常量 - Fortran教程
常量指的是该程序不能在其执行期间改变的固定值。这些固定的值也被称为文字。
常量可以是任何像一个整数的基本数据类型的常量,浮点常量,字符常量,复杂的常量或一个字符串字面量。只有两个逻辑常量:.true. 和 .false.
常量被视为就像普通的变量,但它们的值无法定义后进行修改。
命名常量和文字
有两种类型的常量:
- 字面常量
- 命名常量
一个字面常量有值,但没有名字。
例如,以下是文字常量:
类型 | 例子 |
整型常量 | 0 1 -1 300 123456789 |
实型常量 | 0.0 1.0 -1.0 123.456 7.1E+10 -52.715E-30 |
复数常量 | (0.0, 0.0) (-123.456E+30, 987.654E-29) |
逻辑常量 | .true. .false. |
字符常量 | "PQR" "a" "123'abc$%#@!"" a quote "" "'PQR' 'a' '123"abc$%#@!'' an apostrophe '' ' |
命名常量的值和名称。
命名常量应该在程序或过程的开始声明,就像一个变量的类型声明,说明其名称和类型。命名常量与参数属性声明。例如,
real, parameter :: pi = 3.1415927
例子
下面的程序计算的位移,由于重力作用下垂直运动。
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运算符 - Fortran教程
运算符是一个符号,它告诉编译器执行特定的数学或逻辑操作。 Fortran语言为运算符提供了以下几种类型:
- 算术运算符
- 关系运算符
- 逻辑运算符
让我们一个接一个来看看所有这些类型的运算符。
算术运算符
下表列出了所有Fortran语言支持的算术运算符。假设变量A=5和变量B=3则:
运算符 | 描述 | 例子 |
+ | 加法运算符,相加两个操作数。 | A + B = 8 |
- | 减法运算,第一减去第二操作数。 | A - B = 2 |
* | 乘法运算符,相乘两个操作数。 | A * B = 15 |
/ | 除法运算符,通过分子除以分母。 | A / B = 1 |
** | 乘方运算,计算一个操作数的幂。 | A ** B = 125 |
关系运算符
下表列出了所有Fortran语言支持的关系运算符。假设变量A=10和变量B=20,则:
操作符 | 等量 | 描述 | 示例 |
== | .eq. | 检查两个操作数的值相等与否,如果是,则条件变为真。 | (A == B) 不为 true. |
/= | .ne. | 检查,两个操作数的值相等与否,如果值不相等,则条件变为真。 | (A != B) 为 true. |
> | .gt. | 检查,左操作数的值是否大于右操作数的值,如果是的话那么条件为真。 | (A > B) 不为true. |
< | .lt. | 检查,左操作数的值是否小于右操作数的值,如果是的话那么条件为真。 | (A < B) 为 true. |
>= | .ge. | 检查,左边的操作数的值是否大于或等于右操作数的值,如果是,则条件变为真。 | (A >= B) 不为 true. |
<= | .le. | 检查,左边的操作数的值是否小于或等于右操作数的值,如果是,则条件变为真。 | (A <= B) 为 true. |
逻辑运算符
逻辑运算符在Fortran语言工作只能在逻辑值.true. 和.false。
下面的表列出了所有由Fortran语言支持的逻辑运算符。假设变量A=.true。和变量B=.false ,则:
操作符 | 描述 | 示例 |
.and. | 所谓逻辑与运算符。如果这两个操作数都为非零,则条件变为真。 | (A .and. B) 为 false. |
.or. | 所谓逻辑OR运算符。如果有两个操作数不为零,则条件变为真。 | (A .or. B) 为 true. |
.not. | 所谓逻辑非运算符。使用反转操作数的逻辑状态。如果条件为真,则逻辑非运算符将返回false。 | !(A .and. B) 为 true. |
.eqv. | 所谓逻辑上相当于运算符。用于检查两个逻辑值等价。 | (A .eqv. B) 为 false. |
.neqv. | 所谓逻辑非对等操作。用于检查两个逻辑值的非对等。 | (A .neqv. B) 为 true. |
Fortran语言运算符优先级
运算符优先级来确定条件的表达式中的分组。这会影响一个表达式的求值。某些运算符的优先级高于其他;例如,乘法运算符的优先级比加法运算符更高。
例如x= 7+ 3 2;这里,x被赋值13,而不是20,因为运算符的优先级高于+,所以它首先被乘以3 * 2,然后再加上7。
这里,具有最高优先级运算符出现在表的顶部,那些具有最低出现在底部。在一个表达式,更高的优先级运算符将首先计算。
分类 | 运算符 | 关联 |
逻辑NOT和负号 | .not. (-) | 从左到右 |
幂 | ** | 从左到右 |
乘 | * / | 从左到右 |
加 | + - | 从左到右 |
关系 | < <= > >= | 从左到右 |
相等 | == != | 从左到右 |
逻辑与 | .and. | 从左到右 |
逻辑或 | .or. | 从左到右 |
赋值 | = | 从右到左 |
Fortran选择决策 - Fortran教程
决策结构需要程序员指定的一个或多个条件进行评估计算或由程序进行测试,如果该条件被确定为真,则一条或多条语句将被执行,如果要被执行的其它语句条件被确定为假的则选择其它语句块。
以下是在大多数编程语言中的一个典型的决策结构的一般形式:
Fortran提供决策构建以下类型。
语句 | 描述 |
if… then… end if 语句由一个逻辑表达式后跟一个或多个语句。 | |
if… then语句可以后跟一个可选的 else statement, 它执行时,逻辑表达式为假。 | |
if 语句构建体可具有一个或多个可选的 else-if 结构。当 if 条件不满足,则紧跟 else-if 执行。当 else-if 还失败,其继续 else-if 语句(如果有的话)被执行,依此类推。 | |
可以使用一个 if 或 else if 语句在另外一个 if 或 else if 语句内部 | |
Select Case语句允许一个变量的值对的列表,平等进行测试。 | |
可以使用一个SELECT CASE语句中的另一个选择case语句。 |
Fortran循环 - Fortran教程
可能有一种情况,当需要执行代码块多数。在一般情况下,语句顺序执行:在一个函数的第一条语句,首先执行,然后是第二个。。。等等。
编程语言提供了多种控制结构,使更复杂的执行路径。
循环语句允许我们执行语句的语句多次或组,然后下面是在大多数的编程语言中的循环语句的一般形式为:
Fortran语言提供了循环结构的以下类型的循环处理的要求。点击以下链接,查看其详细信息。
循环类型 | 描述 |
该构建体使得语句或一系列语句迭代进行,当一个给定的条件为真。 | |
重复声明语句或一组,当给定的条件为真。它测试的条件执行循环体之前。 | |
可以使用一个或多个循环结构在其他循环结构里面。 |
循环控制语句
循环控制语句改变其正常的顺序执行。当执行离开循环范围,在该范围内创建的所有对象自动销毁。
Fortran语言支持以下控制语句。点击以下链接,查看其详细信息。
控制语句 | 描述 |
如果被执行exit语句则会退出该循环,并且该程序的继续执行第一个可执行语句结束之后的语句执行。 | |
如果执行了一个循环语句,则程序继续到下一次迭代的起始位置。 | |
如果想执行的程序停止,可以插入声明一个stop语句 |
Fortran字符 - Fortran教程
Fortran语言可以把字符作为单个字符或连续的字符串。
字符可以是从基本的字符集,即从字母,十进制数字,下划线和21特殊字符所采取的任何符号。
字符常量是一个固定的值的字符串。
内部数据类型的字符存储字符和字符串。字符串的长度可以通过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. Beans'
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. Beans'
print *, 'Here is ', name
print *, greetings
end program hello
当编译并执行上述程序,将产生以下结果:
Here is Mr.Rowan Atkinson
A big hello from Mr.Bean
一些字符函数
下表显示描述一些常用字符的函数:
函数 | 描述 |
len(string) | 它返回字符串的长度 |
index(string,sustring) | 在一个字符串找出子串的位置,如果没有找到则返回0。 |
achar(int) | 将整数转换成一个字符 |
iachar(c) | 它可将一个字符转换为整数 |
trim(string) | 它返回去掉尾随空格的字符串。 |
scan(string, chars) | 它会搜索“string”由左到右(除非back=.true)包含在“string”任何字符的第一次出现。它返回一个整数,该字符,或零的位置,如果没有文字的“字符”已被找到。 |
verify(string, chars) | 它扫描“string”由左到右(除非back=.true)不包含在“string”任何字符的第一次出现。它返回一个整数,该字符的位置,如果只在“字符”的字符被找到,或者没有找则返回零。 |
adjustl(string) | 它留下左截于“string”包含的字符 |
adjustr(string) | 它留下右截于“string”包含的字符 |
len_trim(string) | 它返回一个整数等于“string”(len(string))减去尾随空白的数量 |
repeat(string,ncopy) | 它返回一个字符串长度等于“ncopy”次数“string”的长度,并含有“string”的“ncopy”串联拷贝 |
实例 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
这个例子演示了如何使用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 is Mr. Rowan Atkinson
Here is Mr. Rowan Atkinson
示例 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
检查词法顺序字符
下面的函数确定的字符的词法序列:
函数 | 描述 |
lle(char, char) | 进行比较的第一个字符是否是词汇上小于或等于所述第二字符 |
lge(char, char) | 进行比较的第一个字符是否是词汇上大于或等于所述第二字符 |
lgt(char, char) | 进行比较的第一个字符是否是词汇上比第二字符大 |
llt(char, char) | 比较第一个字符是否是词汇上比小于第二字符 |
示例 4
下面的函数演示了如何使用:
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
当编译并执行上述程序,将产生以下结果:
a is lexically greater than A
B is lexically greater than A
A is lexically less than a
A is lexically less than B
Fortran字符串 - Fortran教程
Fortran语言可以把字符作为单个字符或连续的字符串。
字符串可以是只有一个长度的字符,或者它甚至可以是零长度。在Fortran语言,字符常量是一对双引号或单引号之间字符内容。
内部数据类型的字符存储字符和字符串。字符串的长度可以通过len个符来指定。如果没有指定长度,它是长度是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
字符串连接
连接运算符//,连接字符串。
下面的例子说明了这一点:
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
例子
下面的示例使用 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函数接受一个字符串,并删除所有尾随空格后返回输入字符串。
例子
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 需要一个字符串,并通过删除尾随空格和追加作为前导空格返回。
例子
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 函数有两个字符串,并检查是否第二个字符串的第一个字符串的子串。如果第二个参数是第一个参数的子字符串,然后返回一个整数,是第一个字符串第二个字符串的开始索引,否则返回零。
例子
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
当编译并执行上述程序,将产生以下结果:
test is found at index: 11
Fortran数组 - Fortran教程
数组可以存储相同类型的元件的固定大小的连续集合。数组是用来存储数据的集合,但它往往是更加有用认为数组为相同类型的变量的集合。
所有数组由连续的存储单元。最低的地址对应于所述第一元件和所述最高地址的最后一个元素。
| --- | --- | --- | --- | --- | | Numbers(1) | Numbers(2) | Numbers(3) | Numbers(4) | … |
数组可以是一维的(如向量),二维(如矩阵),Fortran允许最多创建7维数组。
声明数组
数组的尺寸属性声明。
例如,声明含有5个元素的实数的一个一维阵列命名号编写,
real, dimension(5) :: numbers
数组的各个元素通过指定其下标引用。数组的第一元件具有一个的下标。数组数字包含五个实变量- numbers(1), numbers(2), numbers(3), numbers(4), 和numbers(5)。
要创建一个5×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 /)
请注意,不存在括号“(”和背斜杠“/”之间所允许有空格
例子
下面的例子演示了上面讨论的概念。
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
2
3
4
3
4
5
4
5
6
1.50000000
3.20000005
4.50000000
0.899999976
7.19999981
数组相关某些术语
下表给出了一些阵列相关的术语:
术语 | 意思 |
Rank | 它的尺寸数组具有的数目。例如,对于数组命名矩阵,秩为2,并且对数组命名号,秩为1。 |
Extent | 它是沿一维中的元素的数量。例如,阵列数字具有范围5和命名矩阵阵列具有在两个维度范围3。 |
Shape | 数组的形状是一维整数数组,包含在每一维的元素(程度)的数量。例如,对于数组基质,形状为(3,3)和数组数字它是(5)。 |
Size | 它是元素的数组中包含的数量。对于数组矩阵,它是9,而对于数字阵列,其为5。 |
数组传递给过程
可以传递一个数组到过程作为参数。下面的例子演示了这一概念:
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
让我们编译和运行上面的程序,这将产生以下结果:
1
2
3
4
5
在上面的例子中,此子程序 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函数,以获得阵列的大小。
让我们编译和运行上面的程序,这将产生以下结果:
1
2
3
4
5
6
7
8
9
10
数组部分
到目前为止,我们已经提到了整个数组,Fortran语言提供了一种简单的方法来引用几个元素,或者一个数组的一部分,使用单条语句。
访问一个数组片段,需要提供的下限和上限的部分,以及一个跨度(增量),对于所有的尺寸。这种表示法被称为下标三元组:
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
数组内部函数
FORTRAN 90/95提供了一些固有的程序。它们可分为7类。
Fortran动态数组 - Fortran教程
动态数组是一种数组,其尺寸在编译时不知道,而是在执行时才已知/确定的。
动态数组的属性使用 allocatable 声明。 .
例如,
real, dimension (:,:), allocatable :: darray
数组的秩,即尺寸,必须提到但是,分配内存以这样的阵列,可以使用allocate函数。
allocate ( darray(s1,s2) )
该阵列使用后,在该程序中,所创建的存储器应该使用 deallocate 函数解除
deallocate (darray)
示例
下面的例子演示了上面讨论的概念。
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
使用data语句
data 语句可用于初始化多个阵列,或用于阵列部分的初始化。
data 语句的语法是:
data variable / list / ...
示例
下面的例子演示了这一概念:
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:
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
使用where语句
where语句可以使用数组中的某些元素在一个表达式,根据一些逻辑条件的结果。它允许表达的执行在一个元素上,如果给定的条件为真。
例子
下面的例子演示了这一概念:
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导出数据类型 - Fortran教程
Fortran语言可以定义导出的数据类型。导出的数据类型也被称为一个结构,它可以包含不同类型的数据对象。
导出的数据类型被用来代表一个记录。例如要跟踪在图书馆的书,可能希望跟踪的每本书有如下属性:
- 标题- Title
- 作者 - Author
- 科目 - Subject
- 编号 - Book ID
定义一个导出的数据类型
定义一个派生数据类型,类型和端类型的语句被使用。类型语句定义了一个新的数据类型,项目不止一个成员。类型声明的格式是这样的:
type type_name
declarations
end type
这里是会声明书的结构方式:
type Books
character(len=50) :: title
character(len=50) :: author
character(len=150) :: subject
integer :: book_id
end type Books
访问结构成员
一个派生数据类型的对象被称为结构
类型书籍(Books) 的结构像一个类型声明语句创建如下:
type(Books) :: book1
结构的组成部分可以使用该组件选择字符(%)进行访问 :
book1%title = "C Programming"
book1%author = "Nuha Ali"
book1%subject = "C Programming Tutorial"
book1%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 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指针 - Fortran教程
在大多数编程语言中,一个指针变量存储对象的内存地址。然而,在Fortran中,指针是具有不是仅仅存储存储器地址多功能性的数据对象。它包含有关特定对象的详细信息,如类型,等级,扩展和存储器地址。
指针是通过分配或指针赋值的目标相关联。
声明一个指针变量
一个指针变量与指针属性声明。
下面的实施例示出了声明指针变量:
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
指针可以指向:
- 动态分配的内存区域
- 数据对象与目标属性相同类型的指针
分配指针的空间
allocate语句可以分配指针对象空间。例如:
program pointerExample
implicit none
integer, pointer :: p1
allocate(p1)
p1 = 1
Print *, p1
p1 = p1 + 4
Print *, p1
end program pointerExample
当上述代码被编译和执行时,它产生了以下结果:
1
5
应该解除分配语句清空该分配的存储空间当它不再需要,并避免未使用的和不可用的存储器空间的积累。
目标和关联
目标是另一个正态变量,空间预留给它。目标变量必须与目标属性进行声明。
一个指针变量使用的关联操作符使目标变量相关联(=>)。
让我们重写前面的例子中,以说明这个概念:
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
当上述代码被编译和执行时,它产生了以下结果:
1
1
5
5
8
8
指针可以是:
- 未定义的
- 关联的
- 未关联的
在上面的程序中,我们使用associated的指针p1与目标t1时,使用=>运算符。相关的函数,测试指针的关联状态。
这个声明无效的关联从一个目标一个指针。
无效非空目标,因为可能有多个指针指向同一个目标。然而空指针指也是无效的。
示例 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
当上述代码被编译和执行时,它产生了以下结果:
1
1
5
5
8
8
8
T
F
T
952754640
952754640
10
10
请注意,每次运行该代码时,内存地址会有所不同。
示例 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基本输入输出 - Fortran教程
到目前为止,我们已看到,我们可以使用打印print语句,以及读取键盘使用read语句,并显示数据输出到屏幕上。这种形式的输入输出是自由格式的I/O,它被称为列表控制的输入输出。
自由格式简单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
其中,
- fmt 是格式规范
- variable-list 要被从键盘读或写在屏幕上的变量的列表
格式规范定义了在其上显示格式化的数据的方式。它由一个字符串,包含了编辑描述符在括号中的列表。
编辑描述符指定的确切格式,例如宽度,其中字符和数字被显示小数点后等,数字位数。
例如:
Print "(f6.3)", pi
下表描述了描述:
描述符 | 描述 | 示例 |
I | 这是用于整数输出。此采用的形式为“rIw.m',其中 r, w 和m 的含义在下面的表格中给出。真正的值在它们字段右侧适应。如果字段宽度不足以容纳一个整数则用星号代替。 | print "(3i5)", i, j, k |
F | 这是用于实数输出。此采用的形式为“rFw.d',其中r, w 和 d 的含义在下面的表格中给出。真正的值在它们字段右侧适应。 如果字段宽度不足够大以容纳所述实数则字段用星号表示。 | print "(f12.3)",pi |
E | 这是用于指数形式实时输出。在“E”描述语句的形式为'rEw.d',其中r,w和d的含义如下表中给出。真正的值在它们字段右侧适应. 如果字段宽度不足够大以容纳所述实数则字段用星号表示。请注意,打印出与三位小数,实数至少10需要一个字段宽度。一个用于尾数,2为零,4为尾数部分和两个用于指数本身的符号。在一般情况下,w≥ d +7。 | print "(e10.3)",123456.0 gives ‘0.123e+06’ |
ES | 这是用于实时输出(科学计数法)。此采用的形式为“rESw.d',其中 r, w 和 d的含义在下面的表格中给出。上述的“E”描述从传统的众所周知的“科学表示法”略有不同。科学表示法具有尾数范围为1.0至10.0对E描述符,它具有在范围0.1到1.0的尾数不同。真实的值在字段的右侧。如果字段宽度不足够大以容纳所述实数则字段用星号表示。这里,字段宽度必须满足 w ≥ d +7 | print "(es10.3)",123456.0 gives ‘1.235e+05’ |
A | 这是用于字符输出。 此采用的形式为“rAw”,其中r和w的含义在下面的表格中给出。字符类型是在它们的字段右侧。如果字段宽度不足于以容纳该字符串则字段的第一个“w”字符的字符串。 | print "(a10)", str |
X | 这是用于空间输出。这需要形式'nX',其中“n”是所需的空间数量。 | print "(5x, a10)", str |
/ | 斜杠描述 - 用于插入空行。这需要的形式'/',并强制下一个数据输出为一个新行。 | print "(/,5x, a10)", str |
以下符号用于格式描述符:
符号 | 描述 |
c | 列数 |
d | 右侧的小数位数为真正的输入或输出 |
m | 要显示的最小位数 |
n | 跳过的空格数 |
r | 重复次数 - 使用描述或组描述符的次数 |
w | 字段宽度- 字符数用于输入或输出 |
示例 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
当上述代码被编译和执行时,它产生了以下结果:
3.142
3.1415927
3.141592741012573
0.3142E-01
实例 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
当上述代码被编译和执行时,它产生了以下结果:(假设用户输入的名称为 Zara)
Enter your first name.
Up to 20 characters, please
Zara
实例 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
当上述代码被编译和执行时,它产生了以下结果:
45
045
300789 45 2
300789 45 2
Tutorials Point
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文件输入输出 - Fortran教程
Fortran语言可以读取数据,并将数据写入到文件中。
在最后一章中,已经看到了如何读取数据和写入数据到终端。在本章中,将学习用Fortran语言提供文件的输入和输出功能。
可以读取和写入到一个或多个文件。OPEN, WRITE, READ 和 CLOSE语句可以实现这一目标。
打开和关闭文件
使用文件之前,必须打开该文件。 open命令用于打开文件进行读取或写入。命令的最简单的形式是:
open (unit = number, file = "name").
然而,open 语句的一般形式:
open (list-of-specifiers)
下表介绍了最常用的修饰符:
修辞符 | 描述 |
[UNIT=] u | 单元数u可以是任何数量范围内9-99,它表明该文件,可以选择任何号码,但在程序中每一个打开的文件必须有一个唯一的数字 |
IOSTAT= ios | 它是在I/O状态标识符和应为整数的变量。如果打开的语句是成功,则返回IOS值为零,否则为一个非零值。 |
ERR = err | 它是一个标签到该控制跳以防有错误。 |
FILE = fname | 文件名,一个字符串。 |
STATUS = sta | 它示出了该文件的先前状态。一个字符串,可以有三个值NEW, OLD 或 SCRATCH。一个临时文件被创建和删除,当关闭或程序结束。 |
ACCESS = acc | 它是该文件的访问模式。可以有两个值SEQUENTIAL 或 DIRECT。默认值是SEQUENTIAL。 |
FORM= frm | 它给该文件的格式的状态。可以有FORMATTED 或UNFORMATTED两个值。默认值是UNFORMATTED |
RECL = rl | 它指定的每个记录中的一个直接访问文件的长度。 |
该文件已被打开后,它由read 和 write语句访问。一旦完成,就应该使用close语句关闭。
close语句的语法如下:
close ([UNIT=]u[,IOSTAT=ios,ERR=err,STATUS=sta])
请注意,括号中的参数是可选的。
示例
这个例子演示了写一些数据到一个新的打开文件。
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 ([UNIT=]u, [FMT=]fmt, IOSTAT=ios, ERR=err, END=s)
write([UNIT=]u, [FMT=]fmt, IOSTAT=ios, ERR=err, END=s)
大部分的修饰符的已在上表中讨论。
END= S说明是程序跳转,当它到达文件结束,声明标签。
示例
这个例子演示了读取和写入到文件。
在这个程序中,从文件中读取,在最后一个例子创建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过程 - Fortran教程
过程是一组执行一个明确定义的任务,可以从程序调用语句。信息(或数据)被传递给调用程序,以过程作为参数。
有两种类型的程序:
- 函数
- 子程序
函数
函数是返回一个数量的过程。函数不修改其参数。
返回数值被称为函数值,并将其表示为函数名。
语法:
函数的语法如下:
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
请注意:
- 必须指定隐含都不在这两个在主程序和过程中。
- 在被调用函数的参数r被称为 dummy argument.
结果选项
如果想返回的值存储在函数名的其他名称,则可以使用result选项。
可以根据指定返回变量名:
function name(arg1, arg2, ....) result (return_var_name)
[declarations, including those for the arguments]
[executable statements]
end function [name]
子程序
子程序没有返回值,但可以修改其参数。
语法
subroutine name(arg1, arg2, ....)
[declarations, including those for the arguments]
[executable statements]
end subroutine [name]
调用子程序
需要使用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
当编译并执行上述程序,它会产生以下结果:
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000
指定参数的意图
意图属性允许指定与参数的过程中使用的意向。下表提供intent属性的值:
值 | 使用为 | 解释 |
in | intent(in) | 用作输入值,而不是在函数中改变 |
out | intent(out) | 用作输出值,它们将被覆盖 |
inout | intent(inout) | 参数都使用和覆盖 |
下面的例子演示了这一概念:
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
当编译并执行上述程序,它会产生以下结果:
The value of the discriminant is
17.0000000
递归过程
递归发生在一个编程语言可以调用同一个函数在函数内。这就是所谓的函数的递归调用。
当一个过程调用本身,直接或间接地被称为递归过程。应该通过其声明之前的字前面递归声明这种类型的程序。
当一个函数被递归使用,则 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
内部过程
当一个过程被包含在程序中,它被称为程序的内部程序。包含一个内部程序的语法如下:
program program_name
implicit none
! type declaration statements
! executable statements
. . .
contains
! internal procedures
. . .
end program program_name
下面的例子演示了这一概念:
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
当编译并执行上述程序,它会产生以下结果:
Before calling swap
a = 2.00000000
b = 3.00000000
After calling swap
a = 3.00000000
b = 2.00000000
Fortran模块 - Fortran教程
模块就像一个包,可以包含函数和子程序,如果正在编写一个非常大的项目,或者函数或子程序需要在多个程序中使用。
模块提供拆分多个文件之间程序的方式。
模块用于:
- 包装子程序,数据和接口块。
- 定义,可以使用多于一个常规全局数据。
- 声明可以选择的任何程序内提供的变量。
- 导入整个模块,可使用在另一个程序或子程序。
模块的语法
模块由两部分组成:
- 规范的一部分,语句声明
- 包含一部分用于子程序和函数定义
模块的一般形式是:
module name
[statement declarations]
[contains [subroutine and function definitions] ]
end module [name]
使用一个模块到程序中
可以将一个程序或子程序通过使用声明的模块:
use name
请注意
- 可以根据需要添加尽可能多的模块,在不同的文件中,并单独编译。
- 一个模块可以在各种不同的程序中使用。
- 一个模块在同一程序中可使用多次。
- 在模块规格说明部分内声明的变量,在模块是全局的。
- 在一个模块中声明的变量成为在模块中使用的任何程序或例程的全局变量。
- 使用声明可以出现在主程序中,或任何其他子程序或模块,它使用所述例程或在一个特定的模块声明的变量。
示例
下面的例子演示了这一概念:
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
当编译并执行上述程序,它会产生以下结果:
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
在一个模块变量和子程序的访问
缺省情况下,在一个模块中的所有的变量和子程序被提供给正在使用的模块代码,通过 use 语句声明。
但是,可以控制模块代码中使用的private 和 public 属性的访问性。当声明一些变量或子程序为私有,这是不可以用在模块之外使用。
示例
下面的例子说明了这个概念:
在前面的例子中,有两个模块变量,e和PI。把它们设置为private并观察输出:
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
当编译和执行上面的程序,它提供了以下错误信息:
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
由于e 和 pi两者都声明为private,module_example不能再访问这些变量程序。
但是其他模块子程序可以访问它们:
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
当编译并执行上述程序,它会产生以下结果:
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
Fortran内部函数 - Fortran教程
内部函数为Fortran语言提供一些常见和重要的功能。我们已经讨论过阵列,字符和字符串一些函数。
内部函数可归类为:
- 数值函数
- 数学函数
- 数字查询函数
- 浮点操作函数
- 位操作函数
- 字符函数
- 类函数
- 逻辑函数
- 数组函数
我们在阵列章讨论的阵列功能。在下面的章节中,提供了与其他类别的所有这些功能的简要说明。
函数名称列,
- A 代表任何类型的数值变量
- R 代表一个真实的或整型变量
- X 和 Y 代表实际变量
- Z 代表复数变量
- W 表示实数或复数变量
数值函数
Function | 描述 |
ABS (A) | 返回A的绝对值 |
AIMAG (Z) | 返回复数Z的虚部 |
AINT (A [, KIND]) | 截断Z小数部分接近零,返回一个实数。 |
ANINT (A [, KIND]) | 返回一个实数值,最接近的整数或整数。 |
CEILING (A [, KIND]) | 返回比最小整数大于或等于数A. |
CMPLX (X [, Y, KIND]) | 其转换实数变量X和Y的一些复数X + iY; 如果Y不存在,则使用0。 |
CONJG (Z) | 返回复数Z的复共轭 |
DBLE (A) | 转换A成到双精度实数。 |
DIM (X, Y) | 返回X和Y的正差 |
DPROD (X, Y) | 返回实数 X 和 Y 产生的双精度 |
FLOOR (A [, KIND]) | 提供了比最大的整数小于或等于数A. |
INT (A [, KIND]) | 将其转换为数字(真实或整数)为整数,截断向零的实部。 |
MAX (A1, A2 [, A3,...]) | 返回的参数的最大值,相同类型 |
MIN (A1, A2 [, A3,...]) | 返回的参数的最小值,相同类型 |
MOD (A, P) | 返回用P除以A余数部分,这两个参数类型相同 (A-INT(A/P)*P) |
MODULO (A, P) | 返回一个模P:(A-FLOOR(A/P)*P) |
NINT (A [, KIND]) | 返回一个最接近整数A的数 |
REAL (A [, KIND]) | 将其转换为实数类型 |
SIGN (A, B) | 返回一个乘以P. 符号的绝对值基本上它转移B的标志为A. |
示例
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
当编译并执行上述程序,它会产生以下结果:
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)
数学函数
函数 | 描述 |
ACOS (X) | 返回该反余弦在范围(0,π),以弧度的形式。 |
ASIN (X) | 返回该反正弦在范围(-π/ 2,π/ 2),单位为弧度。 |
ATAN (X) | 返回反正切的范围(-π/ 2,π/ 2),单位为弧度。 |
ATAN2 (Y, X) | 返回反正切的范围(-π,π),以弧度表示。 |
COS (X) | 返回参数的弧度的余弦值。 |
COSH (X) | 返回参数的弧度的双曲余弦值。 |
EXP (X) | 返回X的指数值 |
LOG (X) | 返回X的自然对数值 |
LOG10 (X) | 返回常用对数(10为基数)X的值 |
SIN (X) | 返回参数的弧度的正弦值。 |
SINH (X) | 返回参数的弧度双曲正弦。 |
SQRT (X) | 返回X的平方根 |
TAN (X) | 返回参数的弧度的切线。 |
TANH (X) | 返回参数弧度的双曲正切值。 |
示例
下列程序计算水平和垂直位置x和y表示抛射时间,t:
这里, x = u t cos a 以及 y = u t 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
当编译并执行上述程序,它会产生以下结果:
x: 141.421356 y: -1818.57861
数字查询函数
这些函数的工作在整数模型和浮点运算。该函数返回相同的种类作为变量X,它可以是实数,在某些情况下,拥有整数的性质。
函数 | 描述 |
DIGITS (X) | 返回显著模型的位数。 |
EPSILON (X) | 返回相比一个是几乎可以忽略不计的数目。换句话说,它返回最小值,使得REAL( 1.0, KIND(X)) + EPSILON(X)为不等于REAL( 1.0, KIND(X))。 |
HUGE (X) | 返回模型最多数量 |
MAXEXPONENT (X) | 返回该模型的最大指数 |
MINEXPONENT (X) | 返回该模型的最小指数 |
PRECISION (X) | 返回小数精度 |
RADIX (X) | 返回该模型的基数 |
RANGE (X) | 返回十进制指数范围 |
TINY (X) | 返回该模型的最小正数 |
浮点操作函数
函数 | 描述 |
EXPONENT (X) | 返回一个模型数的指数部分 |
FRACTION (X) | 返回一个数的小数部分 |
NEAREST (X, S) | 返回给定的方向最近的不同处理器编号 |
RRSPACING (X) | 返回型号的邻近给定数量的相对间隔的倒数 |
SCALE (X, I) | 乘以一个实数由基数的整数次幂 |
SET_EXPONENT (X, I) | 返回一个数的指数部分 |
SPACING (X) | 返回型号的绝对间隔接近指定数值 |
位操作函数
函数 | 描述 |
BIT_SIZE (I) | 返回该模型的比特数 |
BTEST (I, POS) | 位测试 |
IAND (I, J) | 逻辑与 |
IBCLR (I, POS) | 清除位 |
IBITS (I, POS, LEN) | 位提取 |
IBSET (I, POS) | 设置位 |
IEOR (I, J) | 异或 |
IOR (I, J) | 包括或 |
ISHFT (I, SHIFT) | 逻辑移位 |
ISHFTC (I, SHIFT [, SIZE]) | 循环移位 |
NOT (I) | 逻辑补 |
字符函数
函数 | 描述 |
ACHAR (I) | 它返回ASCII整理序列中的第i个字符。 |
ADJUSTL (STRING) | 它通过调节删除任何前导空格和插入尾随空白留下的字符串 |
ADJUSTR (STRING) | 它去除右尾随空白和插入前导空格调整字符串。 |
CHAR (I [, KIND]) | 它返回特定机器整理序列中的第i个字符 |
IACHAR (C) | 它返回字符的ASCII码排序序列中的位置。 |
ICHAR (C) | 它返回字符在机器(处理器)特定排序序列中的位置。 |
INDEX (STRING, SUBSTRING [, BACK]) | 它返回SUBSTRING内STRING最左边(最右边如果返回.TRUE。)起始位置。 |
LEN (STRING) | 它返回字符串的长度。 |
LEN_TRIM (STRING) | 它返回一个字符串的长度没有结尾的空白字符。 |
LGE (STRING_A, STRING_B) | 词汇上大于或等于 |
LGT (STRING_A, STRING_B) | 词汇上大于 |
LLE (STRING_A, STRING_B) | 词汇上大于或等于以下 |
LLT (STRING_A, STRING_B) | 词汇上小于 |
REPEAT (STRING, NCOPIES) | 重复并置 |
SCAN (STRING, SET [, BACK]) | 它返回STRING属于集,或者0,如果都不属于最左边(最右边如果返回.TRUE。)字符的索引。 |
TRIM (STRING) | 删除结尾的空白字符 |
VERIFY (STRING, SET [, BACK]) | 验证字符集的字符串 |
类型函数
函数 | 描述 |
KIND (X) | 它返回种类类型的参数值。 |
SELECTED_INT_KIND (R) | 它返回一种为特定网络版的指数范围类型的参数。 |
SELECTED_REAL_KIND ([P, R]) | 实数类型的参数值,指定精度和范围 |
逻辑函数
Function | 描述 |
LOGICAL (L [, KIND]) | 逻辑型的不同种类型参数对象之间转换 |
Fortran数字精度 - Fortran教程
我们已经讨论过了,在旧版本的 Fortran,有两个实型类型:默认的实型和双精度型。
然而,Fortran语言90/95提供了更多通过种指定精度控制实数和整数数据类型。
类型属性
不同类型的数字都在计算机内部存储方式不同。 kind属性允许指定一个数字内部存储。例如,
real, kind = 2 :: a, b, c
real, kind = 4 :: e, f, g
integer, kind = 2 :: i, j, k
integer, kind = 3 :: l, m, n
在上述声明中,实际变量e,f和g 比实型变量 a,b 和 c 更精确。整数变数l,m 和 n,可以存储较大的值,并有更多的存储比整数变量I,J和k有更多位。虽然这是依赖于机器。
示例
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
当编译并执行上述程序,将产生以下结果:
default kind for real is 4
default kind for int is 2
extended kind for real is 8
default kind for int is 4
查询变量的大小
有一些内在的功能,用于询问数字的大小。
例如,bit_size(i)内部函数指定用于存储位数。对于实数,precision(x)内部函数,返回小数位精度的数字,而range(x)内部函数返回指数的十进制范围。
例子
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
当编译并执行上述程序,将产生以下结果:
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
获取类型值
Fortran语言提供了两个内部函数来获得类型值整数和实数的精度:
- selected_int_kind (r)
- selected_real_kind ([p, r])
selected_real_kind函数返回一个整数,一个给定的小数精度p 和十进制指数范围r 的类型的参数值。小数精度是明显的位数,而小数指数范围规定的最小和最大可表示数。因此该范围是从10-r 到 10+r。
例如,selected_real_kind (p = 10, r = 99) 返回所需的10精确到小数点后类型值,和一系列从10-99〜10+99。
示例
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
当编译并执行上述程序,将产生以下结果:
selected_real_kind (p = 10, r = 99) 8
Fortran编程风格 - Fortran教程
编程风格是所有关于下面的一些规则,同时制定方案。这些好的做法传递价值就类似可读性和明确性在程序中。
一个好的程序应该具有以下特点:
- 可读性
- 正确的逻辑结构
- 不言自明的注释和备注
例如,如果做类似下面的注释,它不会有太大的帮助:
! loop from 1 to 10
do i=1,10
但是,如果正在计算二项式系数,需要这个循环nCr,那么像这样的注释是有好处的:
! loop to calculate nCr
do i=1,10
- 缩进代码块,使各个层次的代码清晰。
- 自我检查代码,以确保零会有类似除法,没有数值误错,负实数的负实数或对数平方根。
- 包括代码,以确保变量不采取非法或超范围值,即输入验证。
- 没有把检查是不必要的,并且会减慢执行。例如:
real :: x
x = sin(y) + 1.0
if (x >= 0.0) then
z = sqrt(x)
end if
- 采用适当的算法的代码编写明显。
- 拆分延续长表达式使用标记 ‘&’.
- 富有意义的变量名命名。
Fortran调试程序 - Fortran教程
调试工具用于搜索程序的错误。
通过代码调试器的程序步骤,并允许在程序执行期间,检查变量和其他数据对象的值。
它加载的源代码,运行在调试器中的程序。调试器调试程序是:
- 设置断点,
- 通过源代码步进,
- 设置观察点。
断点指定的程序应该停止,特别是后代码的临界行。这些变量后,程序执行在断点处进行检查。
调试程序也检查了源代码行。
观看点是在需要时进行检查,特别是在一个读或写操作的一些变量的值。
gdb调试器
gdb调试器,GNU调试器一般由Linux操作系统自带。对于X窗口系统,GDB自带的图形界面和程序命名为 xxgdb。
下表提供了GDB的一些命令:
命令 | 目的 |
break | 设置一个断点 |
run | 开始执行 |
cont | 继续执行 |
next | 只执行源代码的下一行,不进一步的任何函数调用 |
step | 通过步入函数情况下,一个函数调用执行源代码的下一行 |
dbx调试器
还有另外一个调试器,dbx调试器,用在Linux。
下表列出了在dbx中的一些命令:
命令 | 目的 |
stop[var] | 设置一个断点当变量var的值更改。 |
stop in [proc] | 它停止执行当过程被进入 |
stop at [line] | 它在指定行设置一个断点 |
run | 开始执行 |
cont | 继续执行 |
next | 只执行源代码的下一行,不进入任何函数调用。 |
step | 通过步入函数情况下,一个函数调用执行源代码的下一行。 |




