Fortran/程序结构
较旧版本的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或更高版本中,空格字符和空行通常无关紧要。某些语句需要空格字符,例如,program
、function
和subroutine
在语句关键字和程序单元标识符之间需要空格字符。
但是,与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