Fortran - 快速指南


Fortran - 概述

Fortran 源自公式翻译系统,是一种通用的命令式编程语言。它用于数字和科学计算。

Fortran 最初由 IBM 在 20 世纪 50 年代开发,用于科学和工程应用。Fortran 在很长一段时间内统治了这个编程领域,并在高性能计算领域变得非常流行,因为。

它支持 -

  • 数值分析与科学计算
  • 结构化编程
  • 数组编程
  • 模块化编程
  • 通用编程
  • 超级计算机上的高性能计算
  • 面向对象编程
  • 并发编程
  • 计算机系统之间的合理程度的可移植性

关于 Fortran 语言的事实

  • Fortran 是由 IBM 的 John Backus 领导的团队于 1957 年创建的。

  • 最初,名称全部大写,但当前的标准和实现仅要求第一个字母大写。

  • Fortran 代表公式翻译器。

  • 它最初是为科学计算而开发的,但对通用编程所需的字符串和其他结构的支持非常有限。

  • 后来的扩展和发展使其成为一种具有良好可移植性的高级编程语言。

  • 原始版本、Fortran I、II 和 III 现在被认为已过时。

  • 仍在使用的最旧版本是 Fortran IV 和 Fortran 66。

  • 目前最常用的版本是:Fortran 77、Fortran 90 和 Fortran 95。

  • Fortran 77 添加了字符串作为一种独特的类型。

  • Fortran 90 添加了各种线程和直接数组处理。

Fortran - 环境设置

在 Windows 中设置 Fortran

G95 是 GNU Fortran 多架构编译器,用于在 Windows 中设置 Fortran。windows版本在windows下使用MingW模拟unix环境。安装程序会处理此问题并自动将 g95 添加到 Windows PATH 变量中。

您可以从这里获取G95的稳定版本

安装程序设置

迷你安装程序设置

如何使用G95

在安装过程中,如果您选择“推荐”选项,g95会自动添加到您的 PATH 变量中。这意味着您只需打开一个新的命令提示符窗口并输入“g95”即可启动编译器。下面找到一些基本命令来帮助您入门。

先生编号 命令与说明
1

g95 –c 你好.f90

将 hello.f90 编译为名为 hello.o 的目标文件

2

g95你好.f90

编译 hello.f90 并将其链接以生成可执行文件 a.out

3

g95 -c h1.f90 h2.f90 h3.f90

编译多个源文件。如果一切顺利,目标文件 h1.o、h2.o 和 h3.o 将被创建

4

g95 -o 你好 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”、“.f95”结尾的名称表示。 f03”和“.F03”。可以指定多个源文件。也可以指定目标文件并将其链接以形成可执行文件。

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 程序都以关键字program开头,以关键字end program 结束,后跟程序名称。

  • 式 none语句允许编译器检查所​​有变量类型是否已正确声明。您必须始终在每个程序开始时使用隐式 none 。

  • Fortran 中的注释以感叹号 (!) 开头,因为此后的所有字符(字符串中除外)都会被编译器忽略。

  • print *命令在屏幕上显示数据。

  • 代码行缩进是保持程序可读的好习惯。

  • Fortran 允许大写和小写字母。Fortran 不区分大小写,字符串文字除外。

基本

Fortran 的基本字符集包含-

  • 字母 A ... Z 和 a ... z
  • 数字 0 ... 9
  • 下划线 (_) 字符
  • 特殊字符 = : + 空白 - * / ( ) [ ] , . $'!“%&;<>?

令牌由基本字符集中的字符组成。标记可以是关键字、标识符、常量、字符串文字或符号。

程序语句由标记组成。

标识符

标识符是用于标识变量、过程或任何其他用户定义项的名称。Fortran 中的名称必须遵循以下规则 -

  • 它不能超过 31 个字符。

  • 它必须由字母数字字符(字母表中的所有字母和数字 0 到 9)和下划线 (_) 组成。

  • 名称的第一个字符必须是字母。

  • 名称不区分大小写

关键词

关键字是为该语言保留的特殊单词。这些保留字不能用作标识符或名称。

下表列出了 Fortran 关键字 -

非 I/O 关键字
可分配的 分配 分配 任务 块数据
称呼 案件 特点 常见的 复杂的
包含 继续 循环 数据 解除分配
默认 双精度 别的 否则如果
别处 结束块数据 结束做 结束函数 万一
终端接口 终端模块 结束程序 结束选择 结束子程序
端部类型 结束在哪里 入口 等价 出口
外部的 功能 如果 隐含的
进出 整数 意图 界面
固有的 种类 逻辑的 模块
名单 无效化 仅有的 操作员 选修的
出去 范围 暂停 指针 私人的
程序 民众 真实的 递归的 结果
返回 节省 选择案例 停止 子程序
目标 然后 类型 类型() 使用
在哪里 尽管
I/O相关关键字
退格键 关闭 结束文件 格式 查询
打开 打印 倒带

Fortran - 数据类型

Fortran 提供了五种内在数据类型,但是您也可以派生自己的数据类型。五种内在类型是 -

  • 整数类型
  • 真实型
  • 复合型
  • 逻辑类型
  • 字符类型

整数类型

整数类型只能保存整数值。以下示例提取通常的四字节整数中可以保存的最大值 -

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、j、k、l、m 或 n 开头的变量名称被视为整型变量,其他为实型变量。但是,您必须声明所有变量,因为这是良好的编程习惯。为此,您可以使用以下语句开始您的程序 -

implicit none

该语句关闭隐式类型。

Fortran - 变量

变量只不过是我们的程序可以操作的存储区域的名称。每个变量应该有一个特定的类型,它决定了变量内存的大小和布局;该内存中可以存储的值的范围;以及可以应用于变量的操作集。

变量的名称可以由字母、数字和下划线字符组成。Fortran 中的名称必须遵循以下规则 -

  • 它不能超过 31 个字符。

  • 它必须由字母数字字符(字母表中的所有字母和数字 0 到 9)和下划线 (_) 组成。

  • 名称的第一个字符必须是字母。

  • 名称不区分大小写。

基于上一章中解释的基本类型,以下是变量类型 -

先生编号 类型和描述
1

整数

它只能保存整数值。

2

真实的

它存储浮点数。

3

复杂的

它用于存储复数。

4

逻辑性

它存储逻辑布尔值。

5

特点

它存储字符或字符串。

变量声明

变量在程序(或子程序)开头的类型声明语句中声明。

变量声明的语法如下 -

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 Point" 
   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 Point         

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)
逻辑常数 。真的。。错误的。
字符常量

“PQR”“a”“123'abc$%#@!”

“ 一句话”“”

'PQR' 'a' '123"abc$%#@!'

' 撇号 '' '

命名常量具有值和名称。

命名常量应该在程序或过程的开头声明,就像变量类型声明一样,指示其名称和类型。命名常量是用参数属性声明的。例如,

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 支持的所有算术运算符。假设变量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) 不正确。
/= .ne。 检查两个操作数的值是否相等,如果值不相等则条件成立。 (A != B) 为真。
> .gt. 检查左操作数的值是否大于右操作数的值,如果是,则条件为真。 (A > B) 不正确。
< .lt. 检查左操作数的值是否小于右操作数的值,如果是,则条件为真。 (A < B) 为真。
>= .ge。 检查左操作数的值是否大于或等于右操作数的值,如果是,则条件为真。 (A >= B) 不正确。
<= .le。 检查左操作数的值是否小于或等于右操作数的值,如果是,则条件为真。 (A <= B) 为真。

逻辑运算符

Fortran 中的逻辑运算符仅适用于逻辑值 .true。和.false。

下表显示了 Fortran 支持的所有逻辑运算符。假设变量 A 保持 .true。并且变量 B 保持 .false。,那么 -

显示示例

操作员 描述 例子
。和。 称为逻辑与运算符。如果两个操作数均非零,则条件为真。 (A 和 B)是错误的。
。或者。 称为逻辑或运算符。如果两个操作数中的任何一个非零,则条件为真。 (A 或 B)是正确的。
。不是。 称为逻辑非运算符。用于反转其操作数的逻辑状态。如果条件为真,则逻辑 NOT 运算符将为假。 !(A 和 B) 为真。
.eqv。 称为逻辑等效运算符。用于检查两个逻辑值是否相等。 (A .eqv. B) 为假。
.neqv。 称为逻辑非等价运算符。用于检查两个逻辑值不相等。 (A .neqv. B) 是正确的。

Fortran 中的运算符优先级

运算符优先级决定表达式中术语的分组。这会影响表达式的计算方式。某些运算符的优先级高于其他运算符;例如,乘法运算符的优先级高于加法运算符。

例如,x = 7 + 3 * 2;此处,x 被分配为 13,而不是 20,因为运算符 * 的优先级高于 +,因此它首先乘以 3*2,然后添加到 7。

在这里,优先级最高的运算符出现在表的顶部,优先级最低的运算符出现在底部。在表达式中,将首先计算优先级较高的运算符。

显示示例

类别 操作员 关联性
逻辑非和负号 。不是。(-) 左到右
求幂 ** 左到右
乘法 * / 左到右
添加剂 + - 左到右
关系型 <<=>>= 左到右
平等 == /= 左到右
逻辑与 。和。 左到右
逻辑或 。或者。 左到右
任务 = 右到左

Fortran - 决策

决策结构要求程序员指定要由程序评估或测试的一个或多个条件,以及如果条件被确定为真则要执行的一个或多个语句,以及可选的如果确定为真则要执行的其他语句条件被确定为假。

以下是大多数编程语言中典型决策结构的一般形式 -

决策

Fortran 提供以下类型的决策结构。

先生编号 声明及说明
1 如果……则构建

if  ...then...end if语句由一个逻辑表达式后跟一个或多个语句组成。

2 如果...则...否则构造

if  ...then语句后面可以跟一个可选的 else 语句,该语句在逻辑表达式为 false 时执行。

3 if...else if...else 语句

if语句构造可以具有一个或多个可选的else -if构造。当if条件失败时,执行紧随其后的else-if 。else-if也失败时,执行其后继else-if语句(如果有),依此类推。

4 嵌套 if 构造

 您可以在另一个 if 或 else if语句中使用一个 if 或 else if 语句。

5 选择案例构造

select case语句  允许测试变量是否与值列表相等。

6 嵌套选择案例构造

您可以在另一个select case 语句中 使用一个 select case语句。

Fortran - 循环

可能存在一种情况,当您需要多次执行一段代码时。一般来说,语句是按顺序执行的:首先执行函数中的第一个语句,然后执行第二个语句,依此类推。

编程语言提供了各种控制结构,允许更复杂的执行路径。

循环语句允许我们多次执行一条语句或一组语句,以下是大多数编程语言中循环语句的一般形式 -

如果有条件的话

Fortran 提供以下类型的循环构造来处理循环要求。单击以下链接查看其详细信息。

先生编号 循环类型和描述
1 做循环

当给定条件为真时,该构造使得能够迭代地执行一个语句或一系列语句。

2 执行 while 循环

当给定条件为真时,重复一个语句或一组语句。它在执行循环体之前测试条件。

3 嵌套循环

您可以在任何其他循环构造中使用一个或多个循环构造。

循环控制语句

循环控制语句改变其正常顺序的执行。当执行离开作用域时,在该作用域中创建的所有自动对象都将被销毁。

Fortran 支持以下控制语句。单击以下链接查看其详细信息。

先生编号 控制语句和描述
1 出口

如果执行了exit语句,则退出循环,程序继续执行到end do语句之后的第一个可执行语句处。

2 循环

如果执行循环语句,程序将在下一次迭代开始时继续。

3 停止

如果您希望停止执行程序,可以插入停止语句

Fortran - 数字

Fortran 中的数字由三种内在数据类型表示 -

  • 整数类型
  • 真实型
  • 复合型

整数类型

整数类型只能保存整数值。以下示例提取通常的四字节整数中可以保存的最大值 -

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

通用函数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)

数字的范围、精度和大小

整数的范围、浮点数的精度和大小取决于分配给特定数据类型的位数。

下表显示了整数的位数和范围 -

位数 最大值 原因
64 9,223,372,036,854,774,807 (2**63)–1
32 2,147,483,647 (2**31)–1

下表显示了实数的位数、最小值和最大值以及精度。

位数 最大值 最小值 精确
64 0.8E+308 0.5E–308 15–18
32 1.7E+38 0.3E–38 6-9

以下示例证明了这一点 -

program rangePrecision
implicit none

   real:: x, y, z
   x = 1.5e+40
   y = 3.73e+40
   z = x * y 
   print *, z
   
end program rangePrecision

当您编译并执行上述程序时,它会产生以下结果 -

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)

现在让我们使用一个较小的数字 -

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

当您编译并执行上述程序时,它会产生以下结果 -

Infinity
0.402144760   

现在让我们看看下溢 -

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

当您编译并执行上述程序时,它会产生以下结果 -

y = 3.73e-60
           1
Warning : Real constant underflows its kind at (1)

Executing the program....
$demo 

0.00000000E+00
Infinity

种类说明符

在科学编程中,人们经常需要了解正在执行工作的硬件平台的数据范围和精度。

内部函数kind()允许您在运行程序之前查询硬件数据表示的详细信息。

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

当您编译并执行上述程序时,它会产生以下结果 -

Integer 4
Real 4
Complex 4

您还可以检查所有数据类型的种类 -

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

当您编译并执行上述程序时,它会产生以下结果 -

Integer 4
Real 4
Complex 4
Character 1
Logical 4

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. 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

一些字符函数

下表显示了一些常用的字符函数及其说明 -

先生编号 功能说明
1

长度(字符串)

它返回字符串的长度

2

索引(字符串,sustring)

它查找子字符串在另一个字符串中的位置,如果未找到则返回 0。

3

阿查尔(整数)

它将整数转换为字符

4

iachar(c)

它将字符转换为整数

5

修剪(字符串)

它返回删除了尾随空格的字符串。

6

扫描(字符串、字符)

它从左到右搜索“字符串”(除非 back=.true),以查找“chars”中包含的任何字符的第一次出现。它返回一个给出该字符位置的整数,如果没有找到“chars”中的任何字符,则返回零。

7

验证(字符串,字符)

它从左到右扫描“字符串”(除非 back=.true),以查找“字符”中未包含的任何字符的第一次出现。它返回一个整数,给出该字符的位置,如果仅找到“chars”中的字符,则返回零

8

调整(字符串)

它左对齐“字符串”中包含的字符

9

调节器(绳)

它正确对齐“字符串”中包含的字符

10

len_trim(字符串)

它返回一个整数,等于“string”的长度 (len(string)) 减去尾随空格的数量

11

重复(字符串,ncopy)

它返回一个长度等于“ncopy”乘以“string”长度的字符串,并包含“ncopy”连接的“string”副本

实施例1

这个例子展示了索引函数的使用-

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

此示例演示了修剪功能的使用-

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

此示例演示了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

检查字符的词汇顺序

以下函数确定字符的词汇序列 -

先生编号 功能说明
1

lle(字符,字符)

比较第一个字符在词法上是否小于或等于第二个字符

2

lge(字符,字符)

比较第一个字符在词法上是否大于或等于第二个字符

3

LGT(字符,字符)

比较第一个字符在词法上是否大于第二个字符

4

llt(字符,字符)

比较第一个字符在词法上是否小于第二个字符

实施例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 中,字符常量在一对双引号或单引号之间给出。

内在数据类型字符存储字符和字符串。字符串的长度可以通过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 isMr.   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

修剪琴弦

修剪函数接受一个字符串,并在删除所有尾随空格返回输入字符串。

例子

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!

琴弦的左右调整

函数adjustmentl接受一个字符串并通过删除前导空格并将其附加为尾随空格来返回它。

函数调整器接受一个字符串并通过删除尾随空格并将其附加为前导空格来返回它。

例子

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

在字符串中搜索子字符串

索引函数接受两个字符串并检查第二个字符串是否是第一个字符串的子字符串。如果第二个参数是第一个参数的子字符串,则返回一个整数,该整数是第一个字符串中第二个字符串的起始索引,否则返回零。

例子

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 - 数组

数组可以存储相同类型元素的固定大小的顺序集合。数组用于存储数据的集合,但将数组视为相同类型的变量的集合通常更有用。

所有数组都由连续的内存位置组成。最低地址对应于第一个元素,最高地址对应于最后一个元素。

数字(1) 数字(2) 数字(3) 数字(4) ……

数组可以是一维的(如向量)、二维的(如矩阵),Fortran 允许您创建最多 7 维的数组。

声明数组

数组是用维度属性声明的。

例如,要声明一个名为 number 的一维数组,该数组由包含 5 个元素的实数组成,您可以这样写:

real, dimension(5) :: numbers

数组的各个元素通过指定其下标来引用。数组的第一个元素的下标为 1。数组numbers包含五个实数变量——numbers(1)、numbers(2)、numbers(3)、numbers(4)和numbers(5)。

要创建名为矩阵的 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 /)

请注意,方括号“(”和反斜杠“/”之间不允许有空格

例子

以下示例演示了上面讨论的概念。

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)
      e