添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

目录

Fortran - 快速指南

转载自 https://iowiki.com/fortran/ ,在此基础上做了一些补充。

Fortran - Overview

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

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

它支持 -

  • 数值分析与科学计算
  • 结构化编程
  • 模块化编程
  • 超级计算机上的高性能计算
  • 面向对象编程
  • 计算机系统之间的合理程度的可移植性
  • 关于Fortran的事实

  • Fortran由IBM的John Backus于1957年领导的团队创建。
  • 最初这个名称曾用全部资本编写,但目前的标准和实施只要求第一个字母为资本。
  • Fortran代表FORmula TRANslator。
  • 最初是为科学计算而开发的,它对字符串和通用编程所需的其他结构的支持非常有限。
  • 后来的扩展和开发使其成为一种具有良好可移植性的高级编程语言。
  • 原始版本,Fortran I,II和III现在已被淘汰。
  • 仍在使用的最旧版本是Fortran IV和Fortran 66。
  • 今天最常用的版本是:Fortran 77,Fortran 90和Fortran 95。
  • Fortran 77添加了字符串作为一种独特的类型。
  • Fortran 90增加了各种线程和直接阵列处理。
  • Fortran - Environment Setup

    在Windows中设置Fortran

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

    你可以从 here 获得稳定版的G95

    如何使用G95

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

    Sr.No 命令和描述

    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“和”.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构造您可以在另一个ifelse if语句中使用ifelse 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语句使用模块代码的程序。

    但是,您可以使用privatepublic属性控制模块代码的可访问性。 当您将某个变量或子例程声明为私有时,它在模块外部不可用。

    例子 (Example)

    以下示例说明了这一概念 -

    在前面的示例中,我们有两个模块变量epi. 让我们将它们设为私有并观察输出 -

    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
    

    当您编译并执行上述程序时,它会给出以下错误消息 -

       ePowerx = e ** x
    Error: Symbol 'e' at (1) has no IMPLICIT type
    main.f95:19.13:
       area = pi * radius**2     
    Error: Symbol 'pi' at (1) has no IMPLICIT type
    12345678
    

    由于epi,都被声明为私有,因此程序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
    123456789101112131415161718192021222324252627282930
    

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

    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
    

    Fortran - Intrinsic Functions

    内在函数是作为Fortran语言的一部分提供的一些常见且重要的函数。 我们已经在Arrays,Characters和String章节中讨论过这些函数中的一些。

    内在函数可以归类为 -

  • 数字查询功能
  • 浮点操作函数
  • 位操作函数
  • 数组函数。
  • 我们在Arrays章节中讨论了数组函数。 在下一节中,我们将简要介绍其他类别的所有这些功能。

    在函数名称列中,

  • A表示任何类型的数字变量
  • R表示实数或整数变量
  • X和Y代表实际变量
  • Z表示复变量
  • W代表实数或复数变量
  • Sr.No 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 1234567891011121314151617

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