Fortran

結構化編程語言
(重定向自Fortran 95

Fortran,可音譯為福傳,源自於「公式翻译」(英語:Formula Translation)的縮寫[3][4],它是通用的编译型指令式编程语言,特别适用于数值计算科学计算。它在1957年由IBM開發出来[5],是世界上第一个被正式采用並流传至今的高级编程語言

Fortran
编程范型多重范型指令式过程式结构化面向对象阵列式泛型
設計者約翰·巴科斯
實作者約翰·巴科斯IBM
发行时间1957年,​67年前​(1957
当前版本
  • Fortran 2023(2023年11月17日)
編輯維基數據鏈接
型態系統強类型靜態
文件扩展名.f, .for, .f90
網站fortran-lang.org 編輯維基數據鏈接
主要實作產品
GFortran, Intel Fortran英语Intel Fortran Compiler, Nvidia/PGI英语The Portland Group CUDA Fortran[1], Silverfrost FTN95英语Silverfrost FTN95, Oracle f95[2], IBM XL Fortran英语IBM XL Fortran
衍生副語言
F英语F (programming language)
啟發語言
Speedcoding英语Speedcoding
影響語言
ALGOL 58, PL/I, BASIC, C, PACT I英语PACT I, MUMPS英语MUMPS, Ratfor英语Ratfor

简介

Fortran最初由IBM在1950年代开发[5],用于科学和工程应用,并随后长时间统治了科学计算编程。它已经在计算密集领域里应用了超过六个年代,比如数值天气预报有限元分析计算流体力学地球物理学计算物理学晶体学计算化学。它是高性能计算的流行语言[6],并被用于世界上最快超级计算机的基准测试和排名[7][8]

Fortran有很多版本,每个都增加扩展却在很大程度上保持与前面版本的兼容性。后续版本已经增加支持了:结构化编程和基于字符数据的处理(FORTRAN 77),阵列编程模块化编程泛型编程(Fortran 90),高性能Fortran (Fortran 95),面向对象编程(Fortran 2003),并发计算(Fortran 2008)和天然的并行计算能力(Coarray Fortran 2008/2018)。

Fortran的设计是很多其他语言的基础。其中最周知的是在1964年推出的BASIC,它基于了FORTRAN II,具有一些语法英语Syntax (programming languages)清理,尤其是更好的逻辑结构[9],和其他在交互式环境中使工作更加容易的变更[10]

起源

 
John Backus(1924年-2007年),他于1953年12月发起FORTRAN项目,于1977年获得图灵奖

在1953年后期,约翰·巴科斯(John W. Backus)向他在IBM的上司提交了一份提案,要为编程他们的IBM 704主机,而开发一种更实用的语言以替代汇编语言[11]:69。历史上Backus的团队包括了程序员Richard Goldberg、Sheldon F. Best、Harlan Herrick、Peter Sheridan、Roy Nutt英语Roy Nutt、Robert Nelson、Irving Ziller、Harold Stern、Lois Haibt英语Lois HaibtDavid Sayre英语David Sayre[12]。它的概念包括更容易的将方程录入计算机,这是J. Halcombe Laning英语J. Halcombe Laning发展出的想法,并且在1952年演示于Laning与Zierler系统英语Laning and Zierler system之中[13]

在1954年11月,Backus等人完成了草案规定《IBM数学公式转译系统FORTRAN》[14],第一本FORTRAN手册出现在1956年10月[15][11]:72,随后在1957年4月交付了第一个FORTRAN编译器[11]:75。这是第一个优化编译器,因为客户不情愿使用高级编程语言,除非它的编译器能够生成接近于手工编码汇编语言性能的代码[16]

尽管编程社区质疑新方法能否胜过手工编码,它将操作一台机器所需的编程语句数目缩减了20倍,因而快速的获得了接受。John Backus在1979年与IBM 雇员杂志《Think》的一次访谈中说道:“我的多数工作出于懒惰。我不喜欢写程序,所以当我工作在IBM 701英语IBM 701上,为计算弹道轨迹书写程序的时候,我开始制造一个编程系统来使得书写程序更加容易”[17]

FORTRAN语言被科学家广泛接纳,用来书写数值计算密集程序,这鼓励编译器作者生产可以生成更快和更高效代码的编译器。在语言中包括复数数据类型英语complex data type,使得Fortran特别适合于技术应用比如电子工程[18]

到了1960年,FORTRAN版本已经可获得于IBM 709英语IBM 709650英语IBM 6501620英语IBM 16207090计算机上。FORTRAN流行性的显著增长,刺激了竞争计算机制造商在它们的机器上提供FORTRAN编译器,因此到了1963年,存在了超过40个FORTRAN编译器。故此,FORTRAN被认为是第一个广泛使用的跨平台编程语言。

提供给IBM 1401英语IBM 1401计算机的FORTRAN,采用了一种创新的63阶段编译器,它完整的运行于只有8000个(六位元)字符的磁芯内存中。这个编译器可以从磁带或者从2200张打孔卡开始运行;它不进一步的使用磁带或磁盘存储。按照Haines的描述[19],它保持程序在内存中并装载覆盖部分,就地逐步将其转换成可执行形式。此文被重印编辑于两版的《编译器剖析》[20]和IBM手册《Fortran规定和操作过程,IBM 1401》[21]之中。这种可执行形式不完全是机器语言;转而浮点数算术、下标、输入/输出和函数引用是解释执行的,这早先于UCSD PascalP-code两个年代。

Fortran的发展平行于编译器技术的早期演进英语History of compiler construction,在理论和编译器设计上的进步,受到为Fortran程序生成高效代码的激励。

FORTRAN

 
IBM 704的Fortran自动编写代码系统》(1956年10月15日),Fortran的第一本程序员参考手册[15]

最早的FORTRAN版本應用於IBM 704系統上[15],包含了32个语句:

  • DIMENSIONEQUIVALENCE语句。
  • 赋值语句。
  • 三态算术IF英语Arithmetic IF语句。[註 1]
  • 檢查异常情況:IF ACCUMULATOR OVERFLOWIF QUOTIENT OVERFLOWIF DIVIDE CHECK;操纵感应开关和感应灯英语front panelSENSE LIGHTIF (SENSE LIGHT)IF (SENSE SWITCH)
  • 无条件GO TO、计算GO TOASSIGN和指派GO TO
  • DO循环。
  • 格式化輸入與輸出:FORMATREADREAD INPUT TAPEWRITE OUTPUT TAPEPRINTPUNCH
  • 非格式化輸入與輸出: READ TAPEREAD DRUMWRITE TAPEWRITE DRUM
  • 其他的輸入與輸出:END FILEREWINDBACKSPACE
  • PAUSESTOPCONTINUE
  • FREQUENCY语句(为编译器提供优化英语Program optimization提示)。[註 2]

演化

Fortran语言时间线
年份 非正式名字 ANSI标准 ISO/IEC标准
1957 FORTRAN
1958 FORTRAN II
1958 FORTRAN III
1961 FORTRAN IV
1966 FORTRAN 66 X3.9-1966
1978 FORTRAN 77 X3.9-1978
1991 Fortran 90 X3.198-1992 1539:1991
1997 Fortran 95 1539-1:1997
2004 Fortran 2003 1539-1:2004
2010 Fortran 2008 1539-1:2010
2018 Fortran 2018 1539-1:2018
2023 Fortran 2023 1539-1:2023
 
FORTRAN發明年代的计算机,仍未使用电传打字机或带有阴极射线管终端,程式碼必須使用键盘打孔机英语Keypunch打在打孔卡上。圖中顯示卡片上表示了一行FORTRAN代码Z(1) = Y + W(1),打孔卡的第1-5列为标号字段,第6列为接续字段,第73-80列有特殊用途。
 
一张Fortran代码表,程序员准备将上面写的代码用打卡机转录到卡片上。现在已不再使用这种方式。

FORTRAN II

1958年IBM又推出FORTRAN II。主要的增强是凭借允许用户书写的子例程和函数,它们通过传递引用的形式参数来返回值,从而支持了过程式编程COMMON语句为子例程提供了访问公共(或称全局)变量的一种方式。增加了如下6個新語句[22]

  • SUBROUTINEFUNCTIONEND
  • CALLRETURN
  • COMMON

接下來的幾年內,FORTRAN II又繼續支援了DOUBLE PRECISIONCOMPLEX数据类型。

早期的FORTRAN编译器在子例程中不支持递归。早期的计算机架构不支持堆栈的概念,当它们直接支持子例程调用的时候,返回位置经常存储在毗邻这个子例程代码的一个固定位置(例如IBM 1130),或一个特定的机器寄存器(IBM 360系列)之中,它们只能在如下条件下允许递归,即由软件来维护一个堆栈,这个返回地址要在进行调用之前存储在堆栈之上,并在这个调用返回之后恢复。尽管没有规定于FORTRAN 77之中,很多F77编译器将其作为一个选项来支持递归,而Burroughs主机英语Burroughs large systems,设计有内建的递归,而将其作为缺省来支持。它在Fortran 90中通过新关键字RECURSIVE而成为标准[23]

简单的FORTRAN II程序

下面的海伦公式程序, 从磁带盘上读取数据,它包含3个5位整数A、B和C作为输入。这里没有“类型”声明可用:名字开始于I、J、K、L、M或N的变量是“定点数”(就是整数),其他的是浮点数。因为这个例子要处理整数,变量的名字开始于字母“I”。在FORTRAN II中变量名字必须开始于字母,并可以后续着字母和数字二者,直到达到六个字符的限制。如果A、B和C不能表示在平面几何中一个三角形的边,程序将结束执行,STOP给出错误代码“1”。否则打印输出行来显示A、B和C的输入值,随后是计算出的作为浮点数的三角形的面积AREA,它占据输出行的10个空位,并显示小数点后2位,这指定于标号601的FORMAT语句中的“F10.2”。

C     通过标准的平方根函数计算三角形面积
C     输入 - 磁带读取器单元5,整数输入
C     输出 - 行式打印机单元6,实数输出
C     输入错误 - 显示错误输出代码1于作业控制列表中
      READ INPUT TAPE 5, 501, IA, IB, IC
  501 FORMAT(3I5)
C     IA、IB和IC不可以是负数或零
C     再进一步,一个三角形的两条边的总和
C     必须大于第三边,所以我们也做此检查
      IF (IA) 777, 777, 701
  701 IF (IB) 777, 777, 702
  702 IF (IC) 777, 777, 703
  703 IF (IA+IB-IC) 777, 777, 704
  704 IF (IA+IC-IB) 777, 777, 705
  705 IF (IB+IC-IA) 777, 777, 799
  777 STOP 1
C     我们使用海伦公式
C     计算三角形的面积
  799 S = FLOATF (IA + IB + IC) / 2.0
      AREA = SQRTF(S * (S - FLOATF(IA)) * (S - FLOATF(IB)) *
     +             (S - FLOATF(IC)))
      WRITE OUTPUT TAPE 6, 601, IA, IB, IC, AREA
  601 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年時已允许內建組合語言代碼以及其他一些特征[24];然而這個版本卻從未作为产品推出。类似于704 FORTRAN和FORTRAN II,FORTRAN III包含了過多的機器依赖性,造成程式碼不易移植到其他機器上的問題。其他厂商提供的早期FORTRAN版本也經常遭受类似的困苦。

FORTRAN IV

自1961年開始,由於客戶的強烈要求,IBM開始發展FORTRAN IV,目的在於移除一些FORTRAN II中過於依賴機器本身的程式碼(例如:READ INPUT TAPE),同時新增一些新特征,比如LOGICAL資料型別(TRUE或者FALSE)、布尔表达式和取代了算术IF语句的逻辑IF语句。FORTRAN IV於1962年推出,最早應用於IBM 7030英语IBM 7030 Stretch(“Stretch”)計算機之上,接着又推出了IBM 7090IBM 7094版本,和后来1966年的IBM 1401英语IBM 1401版本[25]

到了1965年,FORTRAN IV应该已经符合了美国标准协会X3.4.3 FORTRAN工作组开发的标准[26]。在1966年至1968年之间,IBM为其System/360提供了一些FORTRAN IV编译器,每个都以指示了编译器运行需要的最小内存量的字母来命名[27]。字母F、G、H匹配System/360模式编号来指示内存大小,每个字母增长都是二倍[28]

  • 1966 : FORTRAN IV F for DOS/360(64K字节)
  • 1966 : FORTRAN IV G for OS/360(128K字节)
  • 1968 : FORTRAN IV H for OS/360(256K字节)

数字设备公司(DEC)在1967年至1975年之间为PDP-10维护了DECSYSTEM-10 Fortran IV(F40)[29]

大约在这个时候,FORTRAN IV开始成为重要的教育工具和实现,比如滑铁卢大学创造了WATFOR和WATFIV英语WATFIV来简化早期编译器复杂的编译和链接过程。

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包括了:

  • 主程序、SUBROUTINEFUNCTIONBLOCK DATA程序单元。
  • INTEGERREALDOUBLE PRECISIONCOMPLEXLOGICAL数据类型。
  • COMMONDIMENSIONEQUIVALENCE语句。
  • DATA语句,用以指定初始值。
  • 内部和EXTERNAL(例如库)函数。
  • 赋值语句
  • 无条件GO TO、计算GO TOASSIGN和指派GO TO语句。
  • 逻辑IF和算术(三态)IF语句。
  • DO循环语句。
  • READWRITEBACKSPACEREWINDENDFILE语句,用以处理顺序读写。
  • FORMAT语句和赋值格式。
  • CALLRETURNPAUSESTOPCONTINUE语句。
  • 霍尔瑞斯常量英语Hollerith constant,用于DATAFORMAT语句,作为给子程序的实际参数。
  • 最长6个字符的标识符。
  • 注释行。
  • END行。

前面的FORTRAN II版本的海伦公式程序需要进行一些修改来作为FORTRAN 66程序编译。修改包括使用更加机器无关版本的READWRITE语句,并移除不再需要的FLOATF类型转换函数。尽管不是必须的,算术IF语句被重写为使用逻辑IF语句,并配合上CONTINUE以更加结构化的方式来表示。

C     通过标准的平方根函数计算三角形面积
C     输入 - 磁带读取器单元5,整数输入
C     输出 - 行式打印机单元6,实数输出
C     输入错误 - 显示错误输出代码1于作业控制列表中
      READ (5, 501) IA, IB, IC
  501 FORMAT (3I5)
C     IA、IB和IC不可以是负数或零
C     再进一步,一个三角形的两条边的总和
C     必须大于第三边,所以我们也做此检查
      IF (IA .GT. 0 .AND. IB .GT. 0 .AND. IC .GT. 0) GOTO 10
        WRITE (6, 602)
  602   FORMAT (42H IA, IB, AND IC MUST BE GREATER THAN ZERO.)
        STOP 1
   10 CONTINUE
      IF (IA+IB-IC .GT. 0
     +    .AND. IA+IC-IB .GT. 0
     +    .AND. IB+IC-IA .GT. 0) GOTO 20
        WRITE (6, 603)
  603   FORMAT (50H SUM OF TWO SIDES MUST BE GREATER THAN THIRD SIDE.)
        STOP 1
   20 CONTINUE
C     我们使用海伦公式
C     计算三角形的面积
      S = (IA + IB + IC) / 2.0
      AREA = SQRT ( S * (S - IA) * (S - IB) * (S - IC))
      WRITE (6, 601) IA, IB, IC, AREA
  601 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標準版本的修订工作,这得到了计算机商业设备制造商协会CBEMA英语International Committee for Information Technology Standards(曾经的BEMA)的赞助。这个修订标准的最终草案于1977年发表,并在1978年4月被正式批准为新的FORTRAN标准。新标准叫做FORTRAN 77,其官方代号是X3.9-1978,它增加了一些重要特征来弥补FORTRAN 66的许多缺点[30]

  • 块状IFEND IF语句,以及可选的ELSEELSE IF子句,提供改进了的对结构化编程的语言支持。
  • DO循环扩展,包括参数表达式,负数增量,和零行程计数。
  • OPENCLOSEINQUIRE语句,用以改进I/O能力。
  • 直接访问文件I/O。
  • IMPLICIT语句,用来变更或确认对未声明变量的隐含约定,即如果它们的名字开始于I、J、K、L、M或N则是INTEGER(否则为REAL)。
  • CHARACTER数据类型,替代了霍尔瑞斯字符串,极大地扩展了字符输入和输出以及对基于字符的数据进行处理的设施。
  • PARAMETER语句,用以指定常量。
  • SAVE语句,用以持久保存局部变量。
  • 内部函数的通用名称(比如SQRT也接受其他类型的实际参数,例如COMPLEXREAL*16)。
  • 一组内部函数(LGELGTLLELLT),用于字符串的逻辑比较,它基于了ASCII定序顺序

在这次标准修订中,一些特征被删除或以使曾经符合标准的程序失效的方式而更改了。尽管在冲突列表的24个项目中的大多数(参见X3.9-1978的附录A2),解决了在以前标准中允许但很少使用的漏洞和病态情况,少量特定功能被特意删除了,比如:

      DIMENSION A(10,5)
      Y = A(11,1)
  • 将控制转移出离和回入DO循环的范围(也叫做“扩展范围”)。

开发继FORTRAN 77之后的修订标准被反复的推迟,因为标准化过程难以跟上计算和编程实践的快速变化。与此同时,作为“标准FORTRAN”将近十五年,FORTRAN 77成为了编程语言历史上最重要的Fortran方言。

FORTRAN 77版本的海伦公式程序不必需对FORTRAN 66版本程序进行修改。下面的例子展示额外的I/O语句清理,包括使用列表指导(list-directed)的I/O,并将在FORMAT语句中的霍尔瑞斯编辑描述符替代为引述的字符串。它还使用结构化的IFEND IF语句,取代GOTO/CONTINUE语句。

      PROGRAM HERON
C     通过标准的平方根函数计算三角形面积
C     输入 - 默认标准输入单元,整数输入
C     输出 - 默认标准输出单元,实数输出
C     输入错误 - 显示错误输出代码1于作业控制列表中
      READ (*, *) IA, IB, IC
C     IA、IB和IC不可以是负数或零
C     再进一步,一个三角形的两条边的总和
C     必须大于第三边,所以我们也做此检查
      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
      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     我们使用海伦公式
C     计算三角形的面积
      S = (IA + IB + IC) / 2.0
      AREA = SQRT ( S * (S - IA) * (S - IB) * (S - IC))
      WRITE (*, 601) IA, IB, IC, AREA
  601 FORMAT (' A= ', I5, '  B= ', I5, '  C= ', I5, '  AREA= ', F10.2,
     +        ' square units')
      STOP
      END

ANSI标准Fortran的扩展

一個重要的FORTRAN 77实用扩展,是1978年发行的MIL-STD-1753[31]。這個由美國國防部制定的规范,標準化了由多数FORTRAN 77編譯器实现,却並未引入ANSI FORTRAN 77標準之中的很多特征。这些特征最終合併入Fortran 90標準之中。

1991年推出IEEE 1003.9 POSIX標準,為Fortran-77的程式人員提供了POSIX系统上的呼叫[32]。有超過一百種功能呼叫被定義在文档中。允許访问POSIX相容的进程控制、信號处理、檔案系統控制、设备控制、过程定点,以及可移植方式下的串流式輸入/輸出。

Fortran 90

FORTRAN 77的被严重推迟的后续版本,非正式名称是Fortran 90,最终在1991年发行为ISO/IEC标准1539:1991,在1992年发行为ANSI标准。除了将官方拼写从FORTRAN改为Fortran之外,这个重大修订版本增加了很多特征,用来反映自从1978年标准以来演变出的编程实践中的重要变化:

  • 自由格式源代码输入,不再需要在键入语句之前越过前6个字符位置。
  • 小写的Fortran关键字。
  • 最长31个字符的标识符(在以前的标准中为6个字符)。
  • 行内注释。
  • 能够按整体操作数组(或数组节),由此极大地简化了数学和工程计算。
    • WHERE语句用于选择性数组赋值。
    • 数组值的常量和表达式。
    • 整体、部分和遮掩的数组赋值和数组表达式,比如X(1:N)=R(1:N)*COS(A(1:N))
    • 用户定义的数组值的函数和数组构造子。
  • RECURSIVE过程。
  • 模块,将有关联的过程和数据组合在一起,使它们可以被其它程序单元调用,包括限制只允许访问模块的特定部分的能力。
  • 极大地改善了参数传递机制,允许在编译时检查接口
  • 用户书写的泛型过程的接口。
  • 運算子多載
  • 派生(结构化)数据类型。
  • 新的数据类型定义语法,以指定数据类型和变量的其它特性。
  • 动态内存分配,通过ALLOCATABLE特性和ALLOCATEDEALLOCATE语句。
  • POINTER特性,指针赋值和NULLIFY语句,以便于创建和操作动态数据结构
  • 结构化循环构造,使用END DO语句用于循环终止,EXITCYCLE语句,用于有秩序地“跳出”正常的DO循环迭代。
  • SELECTCASE构造,用于多路选择。
  • 用户控制下可移植的数值精度规定。
  • 新的和增强的内部过程。

废弃与删除

不同于以前的修订,在Fortran 90标准文本的附录“B.1 删除特征”中,没有列出任何要删除的特征。任何符合标准的FORTRAN 77程序,在Fortran 90之下也是符合标准的,二者标准都应当能够定义它的行为。

在附录“B.2 废弃特征”中列举了一小组特征,并期望在将来的标准中删除它们。所有这些早期版本特征的功能,都可以用较新的Fortran特征来完成。其中一些为了简化旧程序移植而保留,大多数在Fortran 95中被删除了。

废弃特征 当前状态
算术IF语句 删除
非整数DO形式参数或控制变量 删除
共享的DO循环终止或终止于END DOCONTINUE之外的语句 删除
从块外部分支进入END IF 删除
PAUSE语句 删除
ASSIGN语句和指派GO TO语句 删除
赋值的语句编号和FORMAT指定符 删除
H编辑描述符 删除
替代返回 废弃
计算GO TO语句 废弃
语句函数 废弃
在可执行语句之间的DATA语句 废弃
CHARACTER*形式的CHARACTER声明 废弃
假定字符长度的函数 废弃
固定形式的源代码 废弃

Fortran 95

Fortran 95正式发表为ISO/IEC 1539-1:1997,它僅是一個小改版,其大部份是修正Fortran 90标准的一些較為顯著的問題。雖然如此,Fortran 95仍有不少的擴充,尤其是对高性能Fortran的规定:

  • FOR ALL和嵌套的WHERE结构,用以辅助向量化。
  • 用户定义的PUREELEMENTAL过程。
  • 派生类型成员的缺省初始化,包括指针初始化。
  • 扩展了对数据对象使用初始化表达式的能力。
  • 初始化指针至NULL()
  • 明确了ALLOCATABLE数组的定义,即它们在出离了作用域的时候自动的被释放。

Fortran 95的一个重要补充是ISO技术报告TR-15581:《增强的数据类型设施》,非正式名称是“可分配TR”。这一标准定义了ALLOCATABLE数组的增强的应用,先于完全与Fortran 2003兼容的Fortran编译器而投入使用。这些使用包括将ALLOCATABLE数组作为派生类型成员、用在过程伪参数列表中以及作为函数返回值。

ALLOCATABLE数组比基于POINTER的数组更受欢迎,因为ALLOCATABLE数组是由Fortran 95提供保证的,当它们退出作用域时会被自动释放掉,避免了内存泄漏的可能性。另外,别名也不再是优化数组引用时的一个问题,可以使编译器生成比用指针时更快的代码[33]

Fortran 95的第二个补充是ISO技术报告TR-15580:《浮点异常处理》,非正式名称是“IEEE TR”。这一标准定义了对IEEE浮点算术浮点异常处理的支持。

条件编译和变长字符串

除了强制性的“基础语言”(定义于ISO/IEC 1539-1 : 1997)Fortran 95语言还包括两个可选的模块:

  • 变长字符串(ISO/IEC 1539-2 : 2000)。
  • 条件编译(ISO/IEC 1539-3 : 1998)。

它们一起构成了多部分的国际标准(ISO/IEC 1539)。

现代Fortran

作为由二十一世纪的标准定义的语言,特别是因为它结合了面向对象编程支持和后来的Coarray Fortran英语Coarray Fortran,它经常被称为“现代Fortran”,这个术语在文献中的使用日渐增长[34]

Fortran 2003

Fortran 2003正式发表为ISO/IEC 1539-1:2004,它是介入了很多新特征的重大修订版本[35]ISO Fortran工作组(ISO/IEC JTC 1/SC 22英语ISO/IEC JTC 1/SC 22/WG5)的官方网站有关于Fortran 2003新特征的详细总结[36]

据该文所述,本版本的主要改进包括:

  • 增强了的派生类型:参数化派生类型,改进的可访问性控制,改进的结构构造子和终止器。
  • 支持面向对象编程类型扩展和继承多态,动态类型分配,以及类型绑定过程,提供对抽象数据类型的完全支持。
  • 改善了数据操纵:可分配的成员(结合了IEEE TR 15581),延迟类型形式参数,VOLATILE特性,在数组构造子和分配语句中显式的类型指定,增强的指针,扩展的初始化表达式,增强的内部过程。
  • 增强的输入/输出:异步传输,串流访问,用户指定的派生类型的传输操作,用户指定的在格式转换时的舍入控制,预连接单元的命名常量,FLUSH语句,关键字的规范化,访问错误信息。
  • 过程指针
  • 支持IEEE浮点算法浮点异常处理(结合了IEEE TR 15580)。
  • C语言的交互性。
  • 支持国际化:访问ISO 10646四字节字符,在数值格式化输入/输出中选择小数点或者逗号。
  • 增强与宿主操作系统的集成:访问命令行参数、环境变量和处理器错误信息。

对Fortran 2003的一个重要补充是ISO技术报告TR-19767:《增强的Fortran中模块设施》。这个报告提供了“子模块”,它使得Fortran模块更加类似于Modula-2模块。它们都类似于Ada私有子从单元。这允许模块的规定和实现,可以用分立的程序单元来表达,它改进了大型库的包装,允许尽管发布明确接口却保护商业机密,并防止编译级联。

Fortran 2008

ISO/IEC 1539-1:2010,非正式的叫做Fortran 2008,于2010年9月通过[37][38]。它只是一個小改版,略微更正了Fortran 2003的一些問題,並且合併了ISO/IEC TR 19767:2005的子模块功能。新的功能包括:

  • 子模块,它是用于模块的补充的结构设施;取代了ISO/IEC TR 19767:2005。
  • Coarray Fortran英语Coarray Fortran,它是并行执行模型。
  • DO CONCURRENT英语Scalable parallelism构造,用于没有内部依赖性的循环迭代。
  • CONTIGUOUS特性,用来指定存储格局限制。
  • BLOCK构造,它可以包含具有构造作用域的对象的声明。
  • 递归可分配成员,作为在派生类型中递归指针的替代者。

对Fortran 2008的一个补充是ISO技术规定(TS)29113:2012《进一步的Fortran同C语言的互操作性》[39],它于2012年5月被提交到ISO并获得批准。这个规定增加对C语言访问数组描述符的支持,并允许忽略实际参数的类型和秩。

Fortran 2018

Fortran语言的2018年修订版(Fortran 2018)早先称为Fortran 2015[40],它是一个重大的修订并且发行于2018年11月28日[41]

Fortran 2018结合了两个此前出版的技术规范:

  • ISO/IEC TS 29113:2012《进一步的Fotran同C语言的互操作性》[42]
  • ISO/IEC TS 18508:2015《补充的Fortran并行特征》[43]

此外的变更和新特征包括支持:ISO/IEC/IEEE 60559:2011(在IEEE 754-2019的最新细小修订之前的IEEE浮点数标准)、十六进制输入/输出、IMPLICIT NONE增强和其他变更[44][45][46][47]

Fortran 2023

Fortran 2023(ISO/IEC 1539-1:2023)发表于2023年11月,可从ISO获得[48]

Fortran的特征

Fortran语言的最大特征,是接近数学公式的自然描述,在计算机里具有很高的执行效率。Fortran可以直接对矩阵复数进行运算。其矩陣元素在記憶空間儲存次序,採用了纵列为主英语Row- and column-major order(Column major)次序,Matlab也承襲這點,而C語言則採用横行为主英语Row- and column-major order(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代码例子,使用欧几里德算法计算两个数AB最大公约数

*     euclid.f (FORTRAN 77)
*     使用欧几里德算法找到最大公约数
      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

下面展示编译和运行这个程序的结果:

$ g77 -o euclid euclid.f
$ ./euclid
 A?
24
 B?
36
 The GCD of 24 and 36 is 12.

Fortran 90特色示例

下面的程序展示动态内存分配和基于数组的运算,这是Fortran 90介入的两个特征。要特别注意的是在操纵数组时,未出现DO循环和IF/THEN语句,数学运算应用于作为整体的数组。同样明显的是运用了描述性变量名字和普通代码格式,这符合当代编程风格。这个例子在交互式录入的数据上计算平均值:

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 > 0) average_points = sum(points) / number_of_points

  ! 现在分别只在正数和负数上取平均
  if (count(points > 0.) > 0) positive_average = sum(points, points > 0.) / count(points > 0.)
  if (count(points < 0.) > 0) negative_average = sum(points, points < 0.) / count(points < 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操作系统下:

  • Fortran Power Station 4.0(FPS 4.0),微软公司开发的Fortran编译器。1997年3月转让给DEC公司
  • Digital Visual Fortran(DVF),Fortran Power Station的DEC公司版本,版本号为5.0.x ~ 6.0.x。
  • Compaq Visual Fortran(CVF),1998年1月,DEC公司被康柏公司收购,Digital Visual Fortran更名为Compaq Visual Fortran,版本号为6.5.x ~ 6.6.B。2002年5月康柏公司已并入惠普公司,但CVF并未改名,版本号升级到6.6.C。
  • Intel Fortran英语Intel Fortran Compiler英特尔公司开发的Fortran编译器。惠普购买了CVF技术之后不久,将Windows平台上的从CVF 6.6.C之后Fortran编译器相关权利全部转售给Intel,它需要微软Visual Studio外壳的支持才能实现Visual IDE功能。在Intel手上的版本編號從7.0開始至現在。
  • Absoft Fortran英语Absoft Fortran Compilers
  • Open Watcom
  • Silverfrost FTN95英语Silverfrost FTN95,个人用户可免费使用的Fortran 95编译器套件。支持编译为Win32或.NET可执行程序,内置名为Plato的IDE,也可通过插件支持Visual Studio,调试器使用SDBG。

Linux操作系统下:

FORTRAN数值库

几个著名的Fortran软件包:

參見

注解

  1. ^ 注意:通常人们会认为这一语句对应于IBM 704上的一个三态分支指令。但事实并非如此,704的分支指令只包含了一个目标地址(例如,TZE - 转换AC为零,TNZ - 转换AC为非零,TPL - 转换AC为加,TMI - 转换AC为减)。机器(以及它的后继者如700/7000系列英语IBM 700/7000 series#Later scientific architecture (704/709/7090/7094))确实有一个三态跳转指令(CAS - 比较AC与存储),那可能是这一说法的最初起源,但是用这一指令来执行IF的话,会消耗4个指令词,需要把常数零放入存储中,然后执行三个机器循环,而如果使用转换指令来实现IF的话,只需要1到3个指令词就够了,不需要将常数存入存储,只需要1到3个机器循环来执行。一个优化的编译器如FORTRAN最有可能采用的是更精简的和通常来说更快的转换指令,而不是比较指令(使用指换指令同时也允许FREQUENCY语句来优化IF,而如果使用比较指令的话则无法实现)。同时,比较指令还将-0和+0认为是不同的值,而转换零和转换非零语句将它们视为相同的值。
  2. ^ FORTRAN中的FREQUENCY最初是被用来给算术IF语句的三种分支状态给出可能性的,以供选择代码生成的方式以及生成的代码的基本块的顺序,在全局优化时,会在内存中安排以便于优化。第一个FORTRAN编译器使用这一权重法来在编译时作运行时生成代码的蒙特卡洛模拟。在当时来说是非常复杂的。这一技术最初记载于1957年的一篇关于第一个FORTRAN编译器实现的文章中,作者是J. Backus等人。许多年之后,FREQUENCY语句对代码已经没有作用了,就被作为注释语句对待了,因为编译器不再作这种编译时模拟了。
    以下摘自1957的论文:"FORTRAN自动编码系统",作者:Backus等人,FREQUENCY语句和它在编译时蒙特卡洛模拟运行时的用法,以优化生成的代码。引文:“ The fundamental unit of program is the basic block; a basic block is a stretch of program which has a single entry point and a single exit point. The purpose of section 4 is to prepare for section 5 a table of predecessors (PRED table) which enumerates the basic blocks and lists for every basic block each of the basic blocks which can be its immediate predecessor in flow, together with the absolute frequency of each such basic block link. This table is obtained by an actual "execution" of the program in Monte-Carlo fashion, in which the outcome of conditional transfers arising out of IF-type statements and computed GO TO'S is determined by a random number generator suitably weighted according to whatever FREQUENCY statements have been provided.”

引用

  1. ^ CUDA Fortran. Nvidia. [2023-02-09]. (原始内容存档于2023-03-26). 
  2. ^ Oracle® Developer Studio 12.6: Fortran User's Guide. [2023-02-11]. (原始内容存档于2023-02-11). 
  3. ^ FORTRAN: The Pioneering Programming Language. IBM. 7 March 2012 [2017-07-19]. (原始内容存档于2023-05-21). 
  4. ^ FORTRAN. Encyclopedia Britannica. 14 June 2021 [2021-07-19]. (原始内容存档于2023-10-28). 
  5. ^ 5.0 5.1 John Backus. The history of FORTRAN I, II and III (PDF). Softwarepreservation.org. [19 November 2014]. (原始内容存档 (PDF)于2007-07-26). 
  6. ^ Eugene Loh. The Ideal HPC Programming Language. Queue. 18 June 2010, 8 (6) [2023-02-04]. (原始内容存档于2016-03-04). 
  7. ^ HPL – A Portable Implementation of the High-Performance Linpack Benchmark for Distributed-Memory Computers. [2015-02-21]. (原始内容存档于2015-02-15). 
  8. ^ Q13. What are the benchmarks?. Overview - CPU 2017. SPEC. [2019-11-13]. (原始内容存档于2021-02-25). 
  9. ^ Fifty Years of BASIC. Time. 29 April 2014 [2023-02-04]. (原始内容存档于2016-02-05). 
  10. ^ Szczepaniak, John. A basic history of BASIC on its 50th birthday. Gamasutra. 1 May 2014 [2023-02-04]. (原始内容存档于2021-03-21). 
  11. ^ 11.0 11.1 11.2 Backus, John. The History of Fortran I, II, and III (PDF). IEEE Annals of the History of Computing. October–December 1998, 20 (4): 68–78 [2020-06-17]. doi:10.1109/85.728232. (原始内容存档 (PDF)于3 March 2016).  [1][2]
  12. ^ J. W. Backus; R. J. Beeber; S. Best; R. Goldberg; L. M. Haibt; H. L. Herrick; R. A. Nelson; D. Sayre; P. B. Sheridan; H. Stern; L. Ziller; R. A. Hughes; R. Nutt. The FORTRAN Automatic Coding System (PDF). Western Joint Computer Conference: 188–198. February 1957 [2023-02-07]. doi:10.1145/1455567.1455599. (原始内容存档 (PDF)于2023-02-07). 
  13. ^ Mindell, David. Digital Apollo. Cambridge, MA: MIT Press. 2008: 99. ISBN 978-0-262-13497-2. JSTOR j.ctt5hhn02. OCLC 228031739. 
  14. ^ J.W. Backus, H. Herrick, I. Ziller. Preliminary Report : Specifications for the IBM Mathematical FORmula TRANSlating System, FORTRAN (PDF). Programming Research Group, Applied Science Division, International Business Machines Corporation. November 10, 1954 [2023-02-09]. (原始内容存档 (PDF)于2023-03-06). 
  15. ^ 15.0 15.1 15.2 Backus, John Warner; Beeber, R. J.; Best, Sheldon F.; Goldberg, Richard; Herrick, Harlan L.; Hughes, R. A.; Mitchell, L. B.; Nelson, Robert A.; Nutt, Roy; Sayre, David; Sheridan, Peter B.; Stern, Harold; Ziller, Irving. Sayre, David , 编. The FORTRAN Automatic Coding System for the IBM 704 EDPM: Programmer's Reference Manual (PDF). New York, USA: Applied Science Division and Programming Research Department, International Business Machines Corporation. 1956-10-15: 2, 19–20 [2022-07-04]. (原始内容存档 (PDF)于2022-07-04).  (2+51+1 pages)
  16. ^ Padua, David. The Fortran I Compiler (PDF). Computing in Science and Engineering (CiSE). the Top Algorithms (University of Illinois: IEEE). January–February 2000, 2 (1): 70–75. Bibcode:2000CSE.....2a..70P. doi:10.1109/5992.814661. (原始内容 (PDF)存档于2020-06-17). The Fortran I compiler was the first major project in code optimization. It tackled problems of crucial importance whose general solution was an important research focus in compiler technology for several decades. Many classical techniques for compiler analysis and optimization can trace their origins and inspiration to the Fortran I compiler. 
  17. ^ Claire Stegmann. Pathfinder (PDF). THINK, IBM Corporation. July/August 1979 [2023-02-10]. (原始内容存档 (PDF)于2022-12-17). 
  18. ^ FORTRAN – The First Programming Language for Numeric Calculations. SciHi Blog. 2019-10-15 [2023-02-07]. (原始内容存档于2021-01-04). 
  19. ^ Haines, L. H. Serial compilation and the 1401 FORTRAN compiler. IBM Systems Journal. 1965, 4 (1): 73–80. doi:10.1147/sj.41.0073. 
  20. ^ Lee, John A. N. Anatomy of a Compiler. Van Nostrand Reinhold. 1967. 
  21. ^ Fortran Specifications and Operating Procedures, IBM 1401 (PDF). IBM. C24-1455-2. (原始内容存档 (PDF)于2017-09-23). 
  22. ^ Reference Manual, FORTRAN II for the IBM 704 Data Processing System (PDF). 1958. C28-6000-2. (原始内容存档 (PDF)于2005-10-30). 
  23. ^ USER NOTES ON FORTRAN PROGRAMMING (UNFP). Ibiblio.org. [15 September 2014]. (原始内容存档于2023-03-07). 
  24. ^ Irving Ziller. Description of Source Language Additions to the FORTRAN II System (PDF). 1958 [2023-02-10]. (原始内容存档 (PDF)于2022-12-17). 
  25. ^ Fortran IV Language Specifications, Program Specifications, and Operating Procedures, IBM 1401, 1440, and 1460 (PDF). IBM. April 1966. C24-3322-2. (原始内容存档 (PDF)于2017-09-23). 
  26. ^ McCracken, Daniel D. Preface . A Guide to FORTRAN IV Programming. New York: Wiley. 1965: v. ISBN 978-0-471-58281-6. 
  27. ^ List of FORTRAN Implementations 1957 - 1967. IEEE Annals. 2017 [2017-10-17]. (原始内容存档于2023-02-05). 
  28. ^ IBM System/360 Model 50 Functional Characteristics (PDF). IBM. 1967. A22-6898-1. (原始内容存档 (PDF)于2021-10-29). 
  29. ^ Digital Equipment Corp. DECSYSTEM-10 FORTRAN IV (F40) Programmers Reference Manual (PDF). Github. Digital Equipment Corporation. [15 April 2022]. (原始内容存档 (PDF)于2023-04-04). 
  30. ^ ANSI X3J3-1978 FORTRAN 77. 1978 [2023-02-09]. (原始内容存档于2020-11-11). 
  31. ^ Mil-std-1753. DoD Supplement to X3.9-1978. United States Government Printing Office. [2023-02-09]. (原始内容存档于2023-04-20). 
  32. ^ IEEE 1003.9-1992 - IEEE Standard for InformationTechnology - POSIX(R) FORTRAN 77 Language Interfaces - Part 1: Binding for System Application Program Interface (API) (PDF). IEEE. [2023-02-09]. (原始内容存档 (PDF)于2012-10-05). 
  33. ^ Fortran 95 Reference. Gnu.Org. [10 May 2014]. (原始内容存档于2023-03-07). 
  34. ^ Lionel, Steve. Doctor Fortran in "It's a Modern Fortran World". Intel (was DEC) Fortran forum discussion group. Intel. 30 December 2013 [11 April 2022]. (原始内容存档于2023-03-07). 
  35. ^ Fortran 2003– Last Working Draft. Gnu.Org. [10 May 2014]. (原始内容存档于2021-02-25). 
  36. ^ WG5 completes processing Fortran 2003 and the TR. nag.co.uk. 2004-05-14. 原始内容存档于2004-08-05. . It may also be downloaded as a PDF file at The New Features of Fortran 2003 (PDF). (原始内容存档 (PDF)于2018-01-15). .
  37. ^ N1836, Summary of Voting/Table of Replies on ISO/IEC FDIS 1539-1, Information technology – Programming languages – Fortran – Part 1: Base language (PDF). (原始内容存档 (PDF)于2018-01-15). 
  38. ^ Fortran 2008 – Last Working Draft (PDF). Gnu.Org. [10 May 2014]. (原始内容存档 (PDF)于2014-05-12). 
  39. ^ ISO/IEC TS 29113:2012 – Information technology – Further interoperability of Fortran with C. 
  40. ^ Doctor Fortran in "Eighteen is the new Fifteen". Doctor Fortran. November 20, 2017 [2023-02-09]. (原始内容存档于2023-02-09). 
  41. ^ Fortran 2018. ISO. [30 November 2018]. (原始内容存档于2017-12-01). 
  42. ^ Further Interoperability of Fortran with C (PDF). ISO. [20 November 2017]. (原始内容存档 (PDF)于2017-12-01). 
  43. ^ Additional Parallel Features in Fortran. ISO. [20 November 2017]. 
  44. ^ The New Features of Fortran 2015. ISO. [23 June 2017]. 
  45. ^ Doctor Fortran in "One Door Closes". Doctor Fortran. September 4, 2015 [2023-02-09]. (原始内容存档于2023-02-09). 
  46. ^ Doctor Fortran Goes Dutch: Fortran 2015. Doctor Fortran. August 8, 2013 [2023-02-09]. (原始内容存档于2023-02-09). 
  47. ^ Fortran 2018 Interpretation Document (PDF). 9 October 2018 [2023-01-31]. (原始内容存档 (PDF)于2022-11-08). 
  48. ^ Fortran 2023. wg5-fortran.org. [November 30, 2023]. (原始内容存档于2024-05-23). 

延伸阅读

语言标准
有关标准
其他参考材料

外部链接