Fortran

Fortran，可音译为福传，源自于「公式翻译」（）的缩写，它是通用的编译型指令式编程语言，特别适用于数值计算和科学计算。它在1957年由IBM开发出来，是世界上第一个被正式采用并流传至今的高级编程语言。
简介.
Fortran最初由IBM在1950年代开发，用于科学和工程应用，并随后长时间统治了科学计算编程。它已经在计算密集领域里应用了超过六个年代，比如数值天气预报、有限元分析、计算流体力学、地球物理学、计算物理学、晶体学和计算化学。它是高性能计算的流行语言，并被用于世界上最快超级计算机的基准测试和排名。
Fortran有很多版本，每个都增加扩展却在很大程度上保持与前面版本的兼容性。后续版本已经增加支持了：结构化编程和基于字符数据的处理（FORTRAN 77），阵列编程、模块化编程和泛型编程（Fortran 90），高性能Fortran (Fortran 95），面向对象编程（Fortran 2003），并发计算（Fortran 2008）和天然的并行计算能力（Coarray Fortran 2008/2018）。
Fortran的设计是很多其他语言的基础。其中最周知的是在1964年推出的BASIC，它基于了FORTRAN II，具有一些清理，尤其是更好的逻辑结构，和其他在交互式环境中使工作更加容易的变更。
起源.
在1953年后期，约翰·巴科斯（John W. Backus）向他在IBM的上司提交了一份提案，要为编程他们的IBM 704主机，而开发一种更实用的语言以替代汇编语言。历史上Backus的团队包括了程序员Richard Goldberg、Sheldon F. Best、Harlan Herrick、Peter Sheridan、、Robert Nelson、Irving Ziller、Harold Stern、和。它的概念包括更容易的将方程录入计算机，这是发展出的想法，并且在1952年演示于之中。
在1954年11月，Backus等人完成了草案规定《IBM数学公式转译系统FORTRAN》，第一本FORTRAN手册出现在1956年10月，随后在1957年4月交付了第一个FORTRAN编译器。这是第一个优化编译器，因为客户不情愿使用高级编程语言，除非它的编译器能够生成接近于手工编码汇编语言性能的代码。
尽管编程社区质疑新方法能否胜过手工编码，它将操作一台机器所需的编程语句数目缩减了20倍，因而快速的获得了接受。John Backus在1979年与IBM 雇员杂志《Think》的一次访谈中说道：“我的多数工作出于懒惰。我不喜欢写程序，所以当我工作在上，为计算弹道轨迹书写程序的时候，我开始制造一个编程系统来使得书写程序更加容易”。
FORTRAN语言被科学家广泛接纳，用来书写数值计算密集程序，这鼓励编译器作者生产可以生成更快和更高效代码的编译器。在语言中包括，使得Fortran特别适合于技术应用比如电子工程。
到了1960年，FORTRAN版本已经可获得于、、和7090计算机上。FORTRAN流行性的显著增长，刺激了竞争计算机制造商在它们的机器上提供FORTRAN编译器，因此到了1963年，存在了超过40个FORTRAN编译器。故此，FORTRAN被认为是第一个广泛使用的跨平台编程语言。
提供给计算机的FORTRAN，采用了一种创新的63阶段编译器，它完整的运行于只有8000个（六位元）字符的磁芯内存中。这个编译器可以从磁带或者从2200张打孔卡开始运行；它不进一步的使用磁带或磁盘存储。按照Haines的描述，它保持程序在内存中并装载覆盖部分，就地逐步将其转换成可执行形式。此文被重印编辑于两版的《编译器剖析》和IBM手册《Fortran规定和操作过程，IBM 1401》之中。这种可执行形式不完全是机器语言；转而浮点数算术、下标、输入/输出和函数引用是解释执行的，这早先于UCSD Pascal的P-code两个年代。
Fortran的发展平行于，在理论和编译器设计上的进步，受到为Fortran程序生成高效代码的激励。
FORTRAN.
最早的FORTRAN版本应用于IBM 704系统上，包含了32个语句：
演化.
FORTRAN II.
1958年IBM又推出FORTRAN II。主要的增强是凭借允许用户书写的子例程和函数，它们通过传递引用的形式参数来返回值，从而支持了过程式编程。codice_31语句为子例程提供了访问公共（或称全局）变量的一种方式。增加了如下6个新语句：
接下来的几年内，FORTRAN II又继续支援了codice_38和codice_39数据类型。
早期的FORTRAN编译器在子例程中不支持递归。早期的计算机架构不支持堆栈的概念，当它们直接支持子例程调用的时候，返回位置经常存储在毗邻这个子例程代码的一个固定位置（例如IBM 1130），或一个特定的机器寄存器（IBM 360系列）之中，它们只能在如下条件下允许递归，即由软件来维护一个堆栈，这个返回地址要在进行调用之前存储在堆栈之上，并在这个调用返回之后恢复。尽管没有规定于FORTRAN 77之中，很多F77编译器将其作为一个选项来支持递归，而，设计有内建的递归，而将其作为缺省来支持。它在Fortran 90中通过新关键字codice_40而成为标准。
简单的FORTRAN II程序.
下面的海伦公式程序, 从磁带盘上读取数据，它包含3个5位整数A、B和C作为输入。这里没有“类型”声明可用：名字开始于I、J、K、L、M或N的变量是“定点数”（就是整数），其他的是浮点数。因为这个例子要处理整数，变量的名字开始于字母“I”。在FORTRAN II中变量名字必须开始于字母，并可以后续着字母和数字二者，直到达到六个字符的限制。如果A、B和C不能表示在平面几何中一个三角形的边，程序将结束执行，codice_28给出错误代码“1”。否则输出一行来显示A、B和C的输入值，随后是计算出的作为浮点数的三角形的面积AREA，它占据输出行的10个空位，并显示小数点后2位，这指定于标号904的codice_14语句中的“F10.2”。
C 通过标准的平方根函数计算三角形面积
C 输入 - 磁带读写器单元5，整数输入
C 输出 - 行式打印机，实数输出
C 输入错误 - 输出错误信息并显示错误代码1于作业控制列表中
 READ INPUT TAPE 5, 901, IA, IB, IC
 901 FORMAT (3I5)
C IA、IB和IC不可以是负数或零
C 一个三角形的两条边的总和必须大于第三边
 IF (IA) 110, 110, 101
 101 IF (IB) 110, 110, 102
 102 IF (IC) 110, 110, 103
 103 IF (IA+IB-IC) 120, 120, 104
 104 IF (IA+IC-IB) 120, 120, 105
 105 IF (IB+IC-IA) 120, 120, 199
 110 PRINT 902
 902 FORMAT (42H IA, IB, AN​D IC MUST BE GREATER THAN ZERO.)
 STOP 1
 120 PRINT 903
 903 FORMAT (50H SU​M OF TWO SIDES MUST BE GREATER THAN THIRD SIDE.)
 STOP 1
 199 CONTINUE
C 使用海伦公式计算三角形的面积
 S = FLOATF (IA + IB + IC) / 2.0
 AREA = SQRTF(S * (S - FLOATF(IA)) * (S - FLOATF(IB)) *
 + (S - FLOATF(IC)))
 PRINT 904, IA, IB, IC, AREA
 904 FORMAT (4H A= ,I5,5H B= ,I5,5H C= ,I5,8H AREA= ,F10.2,
 + 13H SQUARE UNITS)
 STOP
 END
FORTRAN III.
IBM继续开发FORTRAN III，至1958年时已允许内建组合语言代码以及其他一些特征；然而这个版本却从未作为产品推出。类似于704 FORTRAN和FORTRAN II，FORTRAN III包含了过多的机器依赖性，造成程式码不易移植到其他机器上的问题。其他厂商提供的早期FORTRAN版本也经常遭受类似的困苦。
FORTRAN IV.
自1961年开始，由于客户的强烈要求，IBM开始发展FORTRAN IV，目的在于移除一些FORTRAN II中过于依赖机器本身的程式码（例如：codice_16），同时新增一些新特征，比如codice_44资料型别（TRUE或者FALSE）、布尔表达式和取代了算术IF语句的逻辑IF语句。FORTRAN IV于1962年推出，最早应用于（“Stretch”）计算机之上，接着又推出了IBM 7090和IBM 7094版本，和后来1966年的版本。
到了1965年，FORTRAN IV应该已经符合了美国标准协会X3.4.3 FORTRAN工作组开发的标准。在1966年至1968年之间，IBM为其System/360提供了一些FORTRAN IV编译器，每个都以指示了编译器运行需要的最小内存量的字母来命名。字母F、G、H匹配System/360模式编号来指示内存大小，每个字母增长都是二倍：
数字设备公司（DEC）在1967年至1975年之间为PDP-10维护了DECSYSTEM-10 Fortran IV（F40）。
大约在这个时候，FORTRAN IV开始成为重要的教育工具和实现，比如滑铁卢大学创造了WATFOR和来简化早期编译器复杂的编译和链接过程。
FORTRAN 66.
早期的FORTRAN语言发展史上最重要的一件大事，也许是美国标准协会（即今日的美国国家标准协会ANSI）的委员们，开始为FORTRAN制定标准规格，它名为“美国标准FORTRAN”。1966年委员会推出两套FORTRAN标准版本，分别定义成FORTRAN（基于FORTRAN IV，它已经充任了事实标准），和Basic FORTRAN（基于FORTRAN II，并移除其机器依赖性）。由第一套标准定义的FORTRAN，官方代号为X3.9-1966，后来被称为FORTRAN 66（仍有很多人习惯称之为FORTRAN IV）。FORTRAN 66有效的成为第一套FORTRAN的工业标准版本。FORTRAN 66包括了：
前面的FORTRAN II版本的海伦公式程序需要进行一些修改来作为FORTRAN 66程序编译。修改包括使用更加机器无关版本的和语句，并移除不再需要的类型转换函数。尽管不是必须的，算术语句被重写为使用逻辑语句，并以更加结构化的方式来表示。
C 通过标准的平方根函数计算三角形面积
C 输入 - 单元5的磁带读取器，整数输入
C 输出 - 单元6的行式打印机，实数输出
C 输入错误 - 输出错误信息并显示错误代码1于作业控制列表中
 READ (5, 901) IA, IB, IC
 901 FORMAT (3I5)
C IA、IB和IC不可以是负数或零
 IF (IA .GT. 0 .AND. IB .GT. 0 .AND. IC .GT. 0) GOTO 110
 WRITE (6, 902)
 902 FORMAT (42H IA, IB, AN​D IC MUST BE GREATER THAN ZERO.)
 STOP 1
 110 CONTINUE
C 一个三角形的两条边的总和必须大于第三边
 IF (IA+IB-IC .GT. 0 .AND.
 + IA+IC-IB .GT. 0 .AND.
 + IB+IC-IA .GT. 0) GOTO 120
 WRITE (6, 903)
 903 FORMAT (50H SU​M OF TWO SIDES MUST BE GREATER THAN THIRD SIDE.)
 STOP 1
 120 CONTINUE
C 使用海伦公式计算三角形的面积
 S = (IA + IB + IC) / 2.0
 AREA = SQRT ( S * (S - IA) * (S - IB) * (S - IC))
 WRITE (6, 904) IA, IB, IC, AREA
 904 FORMAT (4H A= ,I5,5H B= ,I5,5H C= ,I5,8H AREA= ,F10.2,
 + 13H SQUARE UNITS)
 STOP
 END
FORTRAN 77.
在FORTRAN 66标准推出之后，各家编译器厂商不断推出更具扩充性的标准FORTRAN，促使ANSI委员会X3J3于1969年开始著手于1966标准版本的修订工作，这得到了计算机商业设备制造商协会（曾经的BEMA）的赞助。这个修订标准的最终草案于1977年发表，并在1978年4月被正式批准为新的FORTRAN标准。新标准叫做FORTRAN 77，其官方代号是X3.9-1978，它增加了一些重要特征来弥补FORTRAN 66的许多缺点：
在这次标准修订中，一些特征被删除或以使曾经符合标准的程序失效的方式而更改了。尽管在冲突列表的24个项目中的大多数（参见X3.9-1978的附录A2），解决了在以前标准中允许但很少使用的漏洞和病态情况，少量特定功能被特意删除了，比如：
 DIMENSION A(10,5)
 Y = A(11,1)
开发继FORTRAN 77之后的修订标准被反复的推迟，因为标准化过程难以跟上计算和编程实践的快速变化。与此同时，作为“标准FORTRAN”将近十五年，FORTRAN 77成为了编程语言历史上最重要的Fortran方言。
FORTRAN 77版本的海伦公式程序不必需对FORTRAN 66版本程序进行修改。下面的例子展示额外的I/O语句清理，包括使用列表指导（list-directed）的I/O，并将在语句中的霍尔瑞斯编辑描述符替代为引述的字符串。它还使用结构化的和语句，取代/语句。
 PROGRAM HERON
C 通过标准的平方根函数计算三角形面积
C 输入 - 默认标准输入单元，整数输入
C 输出 - 默认标准输出单元，实数输出
C 输入错误 - 输出错误信息并显示错误代码1于作业控制列表中
 READ (*, *) IA, IB, IC
C IA、IB和IC不可以是负数或零
 IF (IA .LE. 0 .OR. IB .LE. 0 .OR. IC .LE. 0) THEN
 WRITE (*, *) 'IA, IB, and IC must be greater than zero.'
 STOP 1
 END IF
C 一个三角形的两条边的总和必须大于第三边
 IF (IA+IB-IC .LE. 0 .OR.
 + IA+IC-IB .LE. 0 .OR.
 + IB+IC-IA .LE. 0) THEN
 WRITE (*, *) 'Sum of two sides must be greater than third side.'
 STOP 1
 END IF
C 使用海伦公式计算三角形的面积
 S = (IA + IB + IC) / 2.0
 AREA = SQRT ( S * (S - IA) * (S - IB) * (S - IC))
 WRITE (*, 901) IA, IB, IC, AREA
 901 FORMAT (' A= ', I5, ' B= ', I5, ' C= ', I5, ' AREA= ', F10.2,
 + ' square units')
 STOP
 END
ANSI标准Fortran的扩展.
一个重要的FORTRAN 77实用扩展，是1978年发行的MIL-STD-1753。这个由美国国防部制定的规范，标准化了由多数FORTRAN 77编译器实现，却并未引入ANSI FORTRAN 77标准之中的很多特征。这些特征最终合并入Fortran 90标准之中。
1991年推出IEEE 1003.9 POSIX标准，为Fortran-77的程式人员提供了POSIX系统上的呼叫。有超过一百种功能呼叫被定义在文档中。允许访问POSIX相容的进程控制、信号处理、档案系统控制、设备控制、过程定点，以及可移植方式下的串流式输入/输出。
Fortran 90.
FORTRAN 77的被严重推迟的后续版本，非正式名称是Fortran 90，最终在1991年发行为ISO/IEC标准1539:1991，在1992年发行为ANSI标准。除了将官方拼写从FORTRAN改为Fortran之外，这个重大修订版本增加了很多特征，用来反映自从1978年标准以来演变出的编程实践中的重要变化：
废弃与删除.
不同于以前的修订，在Fortran 90标准文本的附录“B.1 删除特征”中，没有列出任何要删除的特征。任何符合标准的FORTRAN 77程序，在Fortran 90之下也是符合标准的，二者标准都应当能够定义它的行为。
在附录“B.2 废弃特征”中列举了一小组特征，并期望在将来的标准中删除它们。所有这些早期版本特征的功能，都可以用较新的Fortran特征来完成。其中一些为了简化旧程序移植而保留，大多数在Fortran 95中被删除了。
Fortran 95.
Fortran 95正式发表为ISO/IEC 1539-1:1997，它仅是一个小改版，其大部份是修正Fortran 90标准的一些较为显著的问题。虽然如此，Fortran 95仍有不少的扩充，尤其是对高性能Fortran的规定：
Fortran 95的一个重要补充是ISO技术报告TR-15581：《增强的数据类型设施》，非正式名称是“可分配TR”。这一标准定义了codice_112数组的增强的应用，先于完全与Fortran 2003兼容的Fortran编译器而投入使用。这些使用包括将codice_112数组作为派生类型成员、用在过程伪参数列表中以及作为函数返回值。
codice_112数组比基于codice_115的数组更受欢迎，因为codice_112数组是由Fortran 95提供保证的，当它们退出作用域时会被自动释放掉，避免了内存泄漏的可能性。另外，别名也不再是优化数组引用时的一个问题，可以使编译器生成比用指针时更快的代码。
Fortran 95的第二个补充是ISO技术报告TR-15580：《浮点异常处理》，非正式名称是“IEEE TR”。这一标准定义了对IEEE浮点算术和浮点异常处理的支持。
条件编译和变长字符串.
除了强制性的“基础语言”（定义于ISO/IEC 1539-1 : 1997）Fortran 95语言还包括两个可选的模块：
它们一起构成了多部分的国际标准（ISO/IEC 1539）。
现代Fortran.
作为由二十一世纪的标准定义的语言，特别是因为它结合了面向对象编程支持和后来的，它经常被称为“现代Fortran”，这个术语在文献中的使用日渐增长。
Fortran 2003.
Fortran 2003正式发表为ISO/IEC 1539-1:2004，它是介入了很多新特征的重大修订版本。ISO Fortran工作组（/WG5）的官方网站有关于Fortran 2003新特征的详细总结。
据该文所述，本版本的主要改进包括：
对Fortran 2003的一个重要补充是ISO技术报告TR-19767：《增强的Fortran中模块设施》。这个报告提供了“子模块”，它使得Fortran模块更加类似于Modula-2模块。它们都类似于Ada私有子从单元。这允许模块的规定和实现，可以用分立的程序单元来表达，它改进了大型库的包装，允许尽管发布明确接口却保护商业机密，并防止编译级联。
Fortran 2008.
ISO/IEC 1539-1:2010，非正式的叫做Fortran 2008，于2010年9月通过。它只是一个小改版，略微更正了Fortran 2003的一些问题，并且合并了ISO/IEC TR 19767:2005的子模块功能。新的功能包括：
对Fortran 2008的一个补充是ISO技术规定（TS）29113:2012《进一步的Fortran同C语言的互操作性》，它于2012年5月被提交到ISO并获得批准。这个规定增加对C语言访问数组描述符的支持，并允许忽略实际参数的类型和秩。
Fortran 2018.
Fortran语言的2018年修订版（Fortran 2018）早先称为Fortran 2015，它是一个重大的修订并且发行于2018年11月28日。
Fortran 2018结合了两个此前出版的技术规范：
此外的变更和新特征包括支持：ISO/IEC/IEEE 60559:2011（在IEEE 的最新细小修订之前的IEEE浮点数标准）、十六进制输入/输出、codice_109增强和其他变更。
Fortran 2023.
Fortran 2023（ISO/IEC 1539-1:2023）发表于2023年11月，可从ISO获得。
Fortran的特征.
Fortran语言的最大特征，是接近数学公式的自然描述，在计算机里具有很高的执行效率。Fortran可以直接对矩阵和复数进行运算。其矩阵元素在记忆空间储存次序，采用了（Column major）次序，Matlab也承袭这点，而C语言则采用（Row major）次序。
Fortran自诞生以来广泛地应用于数值计算领域，特别是并行计算和高性能计算领域。很多专用的大型数值运算计算机针对Fortran做了优化。Fortran积累了大量高效而可靠的源程序。Fortran 90、Fortran 95、Fortran 2003、Fortran 2008和Fortran 2018的相继推出，使Fortran语言具备了现代高级编程语言的一些特征。
代码例子.
Hello World.
示例一个在标准输出设备上输出Hello World的简单程序，这种程序通常作为开始学习编程语言时的第一个程序，下面是FORTRAN 77的写法：
 PROGRAM HELLO
C PRINT语句类似WRITE，
C 但是打印到标准输出单元
 PRINT '(A)', 'Hello, world'
 STOP
 END
下面是Fortran 90的写法：
 program HelloWorld
 write (*,*) 'Hello, world!' ! 这是个行内注释
 end program HelloWorld
最大公约数.
下面的FORTRAN 77代码例子，使用欧几里德算法计算两个数codice_139和codice_140的最大公约数：
 PROGRAM EUCLID
 PRINT *, 'A?'
 READ *, NA
 IF (NA.LE.0) THEN
 PRINT *, 'A must be a positive integer.'
 STOP
 END IF
 PRINT *, 'B?'
 READ *, NB
 IF (NB.LE.0) THEN
 PRINT *, 'B must be a positive integer.'
 STOP
 END IF
 PRINT *, 'The GCD of', NA, ' and', NB, ' is', NGCD(NA, NB), '.'
 STOP
 END
 FUNCTION NGCD(NA, NB)
 IA = NA
 IB = NB
 10 IF (IB.NE.0) THEN
 ITEMP = IA
 IA = IB
 IB = MOD(ITEMP, IB)
 GOTO 10
 END IF
 NGCD = IA
 RETURN
 END
下面展示编译和运行这个程序的结果：
$ f77 -o euclid euclid.f
$ ./euclid
 A?
24
 B?
36
 The GCD of 24 and 36 is 12 .
Fortran 90特色示例.
下面的程序展示动态内存分配和基于数组的运算，这是Fortran 90介入的两个特征。要特别注意的是在操纵数组时，未出现循环和/语句，数学运算应用于作为整体的数组。同样明显的是运用了描述性变量名字和普通代码格式，这符合当代编程风格。这个例子在交互式录入的数据上计算平均值：
program average
 ! 读取一些数值并取其平均
 ! 如下所写，如果没有数据点，返回均值为零
 ! 尽管这可能不是预期行为，它保持例子简单
 implicit none
 real, dimension(:), allocatable :: points
 integer :: number_of_points
 real :: average_points, positive_average, negative_average
 average_points = 0.0
 positive_average = 0.0; negative_average = 0.0
 write (*,*) "Input number of points to average:"
 read (*,*) number_of_points
 allocate (points(number_of_points))
 write (*,*) "Enter the points to average:"
 read (*,*) points
 ! 通过总和诸点并除以点数来取平均
 if (number_of_points &gt; 0) average_points = sum(points) / number_of_points
 ! 现在分别只在正数和负数上取平均
 if (count(points &gt; 0.) &gt; 0) &amp;
 positive_average = sum(points, points &gt; 0.) / count(points &gt; 0.)
 if (count(points &lt; 0.) &gt; 0) &amp;
 negative_average = sum(points, points &lt; 0.) / count(points &lt; 0.)
 ! 打印结果到终端标准输出单元6
 write (*,'(a,g12.4)') 'Average = ', average_points
 write (*,'(a,g12.4)') 'Average of positive points = ', positive_average
 write (*,'(a,g12.4)') 'Average of negative points = ', negative_average
 deallocate (points) ! 释放内存
end program average
下面展示编译和运行这个程序的结果：
$ gfortran -o average average.f90
$ ./average
 Input number of points to average:
8 
 Enter the points to average:
0 1 -1 2 -2 3 -3 4
Average = 0.5000 
Average of positive points = 2.500 
Average of negative points = -2.000 
FORTRAN编译器.
Windows操作系统下：
Linux操作系统下：
FORTRAN数值库.
几个著名的Fortran软件包：