跳转到内容

Fortran/程序结构

来自 Wikibooks,开放世界中的开放书籍


较旧版本的Fortran对程序的格式有严格的指导方针。Fortran 90取消了此限制,并接受自由格式代码以及历史固定格式代码。

固定格式

[编辑 | 编辑源代码]

在Fortran 90之前,源代码遵循一个定义明确的固定格式。注释以第一列中的“C”表示,第2-5列保留用于可选的数字语句标号,第6列中的非空格字符表示当前行是前一行的延续,第7至72列可用于程序语句。第73至80列被忽略,通常包含行序列号。不允许有空行。这种严格的格式是Fortran在批处理计算和穿孔卡片输入时代开发的结果。如果程序“套牌”掉落,则使用序列号;如果将穿孔卡片放置在卡片阅读器中并按第73-80列排序,则可以恢复程序顺序。编译器供应商为此格式提供了扩展,但它很少可移植(例如,将制表符解释为6个空格)。

请注意,虽然列位置很重要,但空格字符并不重要。以下程序说明了在固定格式Fortran中使用空格字符的合法用法

C2345678901234567890
      PROGRAM Z
      GOTO11
   11 CONTINUE
      GO TO 780
 780  CONTINUE
      G OTO3 60
 360  CONTINUE
      STOP
      END

虽然此代码在技术上是合法的,但强烈建议使用空格字符来分隔关键字、标签和数据以保持可读性。

Fortran是在ASCII字符集标准化之前开发的,传统上Fortran代码都是用大写字母编写的。变量名限制为六个字符,但这通常由编译器供应商扩展。

自由格式

[编辑 | 编辑源代码]

从Fortran 90开始,源代码不需要固定列格式。在这种情况下,命令可以自由地从任何列开始。72列的限制也已解除。这为缩进提供了更多空间。

program test
    implicit none
    integer four
    four = 4
    write (*,*) four
end program

大小写敏感性

[编辑 | 编辑源代码]

Fortran不区分大小写。Fortran通常用于仅支持大写字母的系统。事实上,语言本身被称为FORTRAN(全部大写)。虽然完全没有必要,但习惯上仍使用全部大写字母键入Fortran命令。这有助于区分在单色显示器和打印机上显示的源代码中的关键字。如今,语法高亮显示可以替代此功能。但是,它可能有助于直观地区分旧版Fortran代码和现代源代码。

空白字符

[编辑 | 编辑源代码]

在Fortran 90或更高版本中,空格字符和空行通常无关紧要。某些语句需要空格字符,例如,programfunctionsubroutine在语句关键字和程序单元标识符之间需要空格字符。

但是,与C、C++和Java等许多其他语言不同,行分隔符“;”是可选的,因此每行代码都可以保持在自己的行上。但是,不建议使用命令分隔符“;”。

程序单元

[编辑 | 编辑源代码]

Fortran程序由程序单元组成。单个源代码文件可以包含多个程序单元,但通常将每个程序单元放在其自己的单独源代码文件中。它们最基本的形式由一系列Fortran语句组成,并以end语句结束。

主程序

[编辑 | 编辑源代码]

每个可执行程序都必须有一个主程序单元。例如,以下是一个完整的可编译和可执行程序。

write (*,*) "Hello, world"
end

但是,使用program语句来指示它是主程序单元会更加清晰。

program main
    write (*,*) "Hello, world!"
end program main

主程序分为几个部分。第一部分应包含模块use语句。接下来是控制是否隐式类型化未声明变量的implicit / implicit none语句。接下来是声明部分,其中声明变量、类型、接口和过程。然后是主程序的可执行语句。最后一部分是内部子程序,由contains语句启动。

program main
    ! Use statements section
    use module_name
    ! Implicit none statement section
    implicit none
    ! Declarations section
    integer :: a
    real :: b
    
    ! Executable section
    write (*,*) "Blah, blah, blah..."
end program main

子程序

[编辑 | 编辑源代码]

程序单元也可以是子程序:它们可以是过程(函数和子例程)、块数据、模块或子模块。

外部子程序
[编辑 | 编辑源代码]

以下代码显示了一个主程序和一个函数。increment函数位于主程序外部,因此需要在主程序的第4行进行声明。

program main
    implicit none
    integer :: a
    integer, external :: increment

    a = increment(34)
    write (*,*) a
end program main

function increment(input) result (output)
    implicit none
    integer :: output
    integer :: input

    output = input + 1
end function increment

但是,函数的接口仍然是隐式的。要显式地声明外部过程,可以使用一个接口来声明所有外部过程的输入和输出。在这种情况下,主程序如下所示。

program main
    implicit none
    integer :: a
    interface
        integer function increment(input)
            integer :: input
        end function
    end interface

    a = increment(34)
    write (*,*) a
end program main
内部子程序

[编辑 | 编辑源代码]

内部子程序不需要显式接口或声明,因为它们是父程序单元的一部分。如果子程序包含在程序单元的contains部分中,则该子程序为内部子程序。

program main
    implicit none
    integer :: a

    a = increment(34)
    write (*,*) a
    
contains

    function increment(input) result (output)
        integer :: output
        integer :: input

        output = input + 1
    end function increment

end program main

子例程

[编辑 | 编辑源代码]

块数据

[编辑 | 编辑源代码]

子模块

[编辑 | 编辑源代码]
华夏公益教科书