Fortran

Fortran，可音譯為福傳，源自於「公式翻譯」（Formula Translation）的縮寫，它是通用的編譯型指令式程式語言，特別適用於數值計算和科學計算。它在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，具有一些語法 (程式語言)清理，尤其是更好的邏輯結構，和其他在交互式環境中使工作更加容易的變更。

## 起源

<image>

在1953年後期，約翰·巴科斯（John W. Backus）向他在IBM的上司提交了一份提案，要為編程他們的IBM 704主機，而開發一種更實用的語言以替代彙編語言。歷史上Backus的團隊包括了程式設計師Richard Goldberg、Sheldon F. Best、Harlan Herrick、Peter Sheridan、Roy Nutt、Robert Nelson、Irving Ziller、Harold Stern、Lois Haibt和David Sayre。它的概念包括更容易的將方程錄入電腦，這是J. Halcombe Laning發展出的想法，並且在1952年演示於Laning與Zierler系統之中。

在1954年11月，Backus等人完成了草案規定《IBM數學公式轉譯系統FORTRAN》，第一本FORTRAN手冊出現在1956年10月，隨後在1957年4月交付了第一個FORTRAN編譯器。這是第一個優化編譯器，因為客戶不情願使用高級程式語言，除非它的編譯器能夠生成接近於手工編碼彙編語言性能的代碼。

儘管編程社區質疑新方法能否勝過手工編碼，它將操作一台機器所需的編程語句數目縮減了20倍，因而快速的獲得了接受。John Backus在1979年與IBM 雇員雜誌《Think》的一次訪談中說道：「我的多數工作出於懶惰。我不喜歡寫程序，所以當我工作在IBM 701上，為計算彈道軌跡書寫程序的時候，我開始製造一個編程系統來使得書寫程序更加容易」。

FORTRAN語言被科學家廣泛接納，用來書寫數值計算密集程序，這鼓勵編譯器作者生產可以生成更快和更高效代碼的編譯器。在語言中包括複數數據類型，使得Fortran特別適合於技術應用比如電子工程。

到了1960年，FORTRAN版本已經可獲得於IBM 709、IBM 650、IBM 1620和7090電腦上。FORTRAN流行性的顯著增長，刺激了競爭電腦製造商在它們的機器上提供FORTRAN編譯器，因此到了1963年，存在了超過40個FORTRAN編譯器。故此，FORTRAN被認為是第一個廣泛使用的跨平台程式語言。

提供給IBM 1401電腦的FORTRAN，採用了一種創新的63階段編譯器，它完整的運行於只有8000個（六位元）字符的磁芯記憶體中。這個編譯器可以從磁帶或者從2200張打孔卡開始運行；它不進一步的使用磁帶或磁碟存儲。按照Haines的描述，它保持程序在記憶體中並裝載覆蓋部分，就地逐步將其轉換成可執行形式。此文被重印編輯於兩版的《編譯器剖析》和IBM手冊《Fortran規定和操作過程，IBM 1401》之中。這種可執行形式不完全是機器語言；轉而浮點數算術、下標、輸入/輸出和函數引用是解釋執行的，這早先於UCSD Pascal的P-code兩個年代。

Fortran的發展平行於編譯器構造歷史，在理論和編譯器設計上的進步，受到為Fortran程序生成高效代碼的激勵。

### FORTRAN

<image>

最早的FORTRAN版本應用於IBM 704系統上，包含了32個語句：

- `DIMENSION`和`EQUIVALENCE`語句。
- 賦值語句。
- 三態算術IF語句。
- 檢查異常情況：`IF ACCUMULATOR OVERFLOW`、`IF QUOTIENT OVERFLOW`和`IF DIVIDE CHECK`；操縱前面板：`SENSE LIGHT`、`IF (SENSE LIGHT)`和`IF (SENSE SWITCH)`。
- 無條件`GO TO`、計算`GO TO`、`ASSIGN`和指派`GO TO`。
- `DO`循環。
- 格式化輸入與輸出：`FORMAT`、`READ`、`READ INPUT TAPE`、`WRITE OUTPUT TAPE`、`PRINT`和`PUNCH`。
- 非格式化輸入與輸出: `READ TAPE`、`READ DRUM`、`WRITE TAPE`和`WRITE DRUM`。
- 其他的輸入與輸出：`END FILE`、`REWIND`和`BACKSPACE`。
- `PAUSE`、`STOP`和`CONTINUE`。
- `FREQUENCY`語句（為編譯器提供程序優化提示）。

## 演化

年份｜非正式名字｜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

<image>

<image>

### FORTRAN II

1958年IBM又推出FORTRAN II。主要的增強是憑藉允許用戶書寫的子例程和函數，它們通過傳遞引用的形式參數來返回值，從而支持了過程式編程。`COMMON`語句為子例程提供了訪問公共（或稱全局）變量的一種方式。增加了如下6個新語句：

- `SUBROUTINE`、`FUNCTION`和`END`。
- `CALL`和`RETURN`。
- `COMMON`。

接下來的幾年內，FORTRAN II又繼續支援了`DOUBLE PRECISION`和`COMPLEX`數據類型。

早期的FORTRAN編譯器在子例程中不支持遞歸。早期的電腦架構不支持堆棧的概念，當它們直接支持子例程調用的時候，返回位置經常存儲在毗鄰這個子例程代碼的一個固定位置（例如IBM 1130），或一個特定的機器寄存器（IBM 360系列）之中，它們只能在如下條件下允許遞歸，即由軟體來維護一個堆棧，這個返回地址要在進行調用之前存儲在堆棧之上，並在這個調用返回之後恢復。儘管沒有規定於FORTRAN 77之中，很多F77編譯器將其作為一個選項來支持遞歸，而Burroughs大型系統，設計有內建的遞歸，而將其作為預設來支持。它在Fortran 90中通過新關鍵字`RECURSIVE`而成為標準。

#### 簡單的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位，這指定於標號904的`FORMAT`語句中的「F10.2」。

```fortranfixed
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, AND IC MUST BE GREATER THAN ZERO.)
      STOP 1
  120 PRINT 903
  903 FORMAT (50H SUM 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中過於依賴機器本身的程式碼（例如：`READ INPUT TAPE`），同時新增一些新特徵，比如`LOGICAL`資料型別（TRUE或者FALSE）、布爾表達式和取代了算術IF語句的邏輯IF語句。FORTRAN IV於1962年推出，最早應用於IBM 7030 Stretch（「Stretch」）電腦之上，接著又推出了IBM 7090和IBM 7094版本，和後來1966年的IBM 1401版本。

到了1965年，FORTRAN IV應該已經符合了美國標準協會X3.4.3 FORTRAN工作組開發的標準。在1966年至1968年之間，IBM為其System/360提供了一些FORTRAN IV編譯器，每個都以指示了編譯器運行需要的最小記憶體量的字母來命名。字母F、G、H匹配System/360模式編號來指示記憶體大小，每個字母增長都是二倍：

- 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）。

大約在這個時候，FORTRAN IV開始成為重要的教育工具和實現，比如滑鐵盧大學創造了WATFOR和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包括了：

- 主程序、`SUBROUTINE`、`FUNCTION`和`BLOCK DATA`程序單元。
- `INTEGER`、`REAL`、`DOUBLE PRECISION`、`COMPLEX`和`LOGICAL`數據類型。
- `COMMON`、`DIMENSION`和`EQUIVALENCE`語句。
- `DATA`語句，用以指定初始值。
- 內部和`EXTERNAL`（例如庫）函數。
- 賦值語句
- 無條件`GO TO`、計算`GO TO`、`ASSIGN`和指派`GO TO`語句。
- 邏輯`IF`和算術（三態）`IF`語句。
- `DO`循環語句。
- `READ`、`WRITE`、`BACKSPACE`、`REWIND`和`ENDFILE`語句，用以處理順序讀寫。
- `FORMAT`語句和賦值格式。
- `CALL`、`RETURN`、`PAUSE`、`STOP`和`CONTINUE`語句。
- 霍爾瑞斯常量，用於`DATA`和`FORMAT`語句，作為給子程序的實際參數。
- 最長6個字符的標識符。
- 注釋行。
- `END`行。

前面的FORTRAN II版本的海倫公式程序需要進行一些修改來作為FORTRAN 66程序編譯。修改包括使用更加機器無關版本的READ和WRITE語句，並移除不再需要的FLOATF類型轉換函數。儘管不是必須的，算術IF語句被重寫為使用邏輯IF語句，並以更加結構化的方式來表示。

```fortranfixed
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, AND 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 SUM 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的許多缺點：

- 塊狀`IF`和`END IF`語句，以及可選的`ELSE`和`ELSE IF`子句，提供改進了的對結構化編程的語言支持。
- `DO`循環擴展，包括參數表達式，負數增量，和零行程計數。
- `OPEN`、`CLOSE`和`INQUIRE`語句，用以改進I/O能力。
- 直接訪問文件I/O。
- `IMPLICIT`語句，用來變更或確認對未聲明變量的隱含約定，即如果它們的名字開始於I、J、K、L、M或N則是`INTEGER`（否則為`REAL`）。
- `CHARACTER`數據類型，替代了霍爾瑞斯字串，極大地擴展了字符輸入和輸出以及對基於字符的數據進行處理的設施。
- `PARAMETER`語句，用以指定常量。
- `SAVE`語句，用以持久保存局部變量。
- 內部函數的通用名稱（比如`SQRT`也接受其他類型的實際參數，例如`COMPLEX`或`REAL*16`）。
- 一組內部函數（`LGE`、`LGT`、`LLE`和`LLT`），用於字串的邏輯比較，它基於了ASCII定序順序。

在這次標準修訂中，一些特徵被刪除或以使曾經符合標準的程序失效的方式而更改了。儘管在衝突列表的24個項目中的大多數（參見X3.9-1978的附錄A2），解決了在以前標準中允許但很少使用的漏洞和病態情況，少量特定功能被特意刪除了，比如：

- 霍爾瑞斯常量和霍爾瑞斯數據，例如：`GREET = 12HHELLO THERE!`。
- 在`FORMAT`規定中讀入H編輯（霍爾瑞斯欄位）描述符。
- 通過下標對數組邊界的翻越索引，例如：

```fortranfixed
      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語句中的霍爾瑞斯編輯描述符替代為引述的字串。它還使用結構化的IF和END IF語句，取代GOTO/CONTINUE語句。

```fortranfixed
      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標準之中。

- `DO WHILE`、`EXIT`、`CYCLE`和`END DO`語句。
- `INCLUDE`語句。
- `IMPLICIT`語句的`IMPLICIT NONE`變體。
- 位操縱內部函數，基於了包含在工業實時Fortran（ANSI/ISA S61.1 (1976)）中的類似的函數。

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年標準以來演變出的編程實踐中的重要變化：

- 自由格式原始碼輸入，不再需要在鍵入語句之前越過前6個字符位置。
- 小寫的Fortran關鍵字。
- 最長31個字符的標識符（在以前的標準中為6個字符）。
- 行內注釋。
- 能夠按整體操作陣列（或陣列節），由此極大地簡化了數學和工程計算。
- `WHERE`語句用於選擇性陣列賦值。
- 陣列值的常量和表達式。
- 整體、部分和遮掩的陣列賦值和陣列表達式，比如

```fortran
X(1:N)=R(1:N)*COS(A(1:N))
```

- 使用者定義的陣列值的函數和陣列構造子。
- `RECURSIVE`過程。
- 模塊，將有關聯的過程和數據組合在一起，使它們可以被其它程序單元調用，包括限制只允許訪問模塊的特定部分的能力。
- 極大地改善了參數傳遞機制，允許在編譯時檢查接口。
- 使用者書寫的泛型過程的接口。
- 運算子多載。
- 派生（結構化）數據類型。
- 新的數據類型定義語法，以指定數據類型和變量的其它特性。
- 動態記憶體分配，通過`ALLOCATABLE`特性和`ALLOCATE`和`DEALLOCATE`語句。
- `POINTER`特性，指針賦值和`NULLIFY`語句，以便於創建和操作動態數據結構。
- 結構化循環構造，使用`END DO`語句用於循環終止，`EXIT`和`CYCLE`語句，用於有秩序地「跳出」正常的`DO`循環迭代。
- `SELECT`...`CASE`構造，用於多路選擇。
- 使用者控制下可移植的數值精度規定。
- 新的和增強的內部過程。

#### 廢棄與刪除

不同於以前的修訂，在Fortran 90標準文本的附錄「B.1 刪除特徵」中，沒有列出任何要刪除的特徵。任何符合標準的FORTRAN 77程序，在Fortran 90之下也是符合標準的，二者標準都應當能夠定義它的行為。

在附錄「B.2 廢棄特徵」中列舉了一小組特徵，並期望在將來的標準中刪除它們。所有這些早期版本特徵的功能，都可以用較新的Fortran特徵來完成。其中一些為了簡化舊程序移植而保留，大多數在Fortran 95中被刪除了。

廢棄特徵｜當前狀態

算術`IF`語句｜刪除

非整數`DO`形式參數或控制變量｜刪除

共享的`DO`循環終止或終止於`END DO`或`CONTINUE`之外的語句｜刪除

從塊外部分支進入`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`結構，用以輔助向量化。
- 使用者定義的`PURE`和`ELEMENTAL`過程。
- 派生類型成員的預設初始化，包括指針初始化。
- 擴展了對數據對象使用初始化表達式的能力。
- 初始化指針至`NULL()`。
- 明確了`ALLOCATABLE`陣列的定義，即它們在出離了作用域的時候自動的被釋放。

Fortran 95的一個重要補充是ISO技術報告TR-15581：《增強的數據類型設施》，非正式名稱是「可分配TR」。這一標準定義了`ALLOCATABLE`陣列的增強的應用，先於完全與Fortran 2003兼容的Fortran編譯器而投入使用。這些使用包括將`ALLOCATABLE`陣列作為派生類型成員、用在過程偽參數列表中以及作為函數返回值。

`ALLOCATABLE`陣列比基於`POINTER`的陣列更受歡迎，因為`ALLOCATABLE`陣列是由Fortran 95提供保證的，當它們退出作用域時會被自動釋放掉，避免了記憶體洩漏的可能性。另外，別名也不再是優化陣列引用時的一個問題，可以使編譯器生成比用指針時更快的代碼。

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，它經常被稱為「現代Fortran」，這個術語在文獻中的使用日漸增長。

### Fortran 2003

Fortran 2003正式發表為ISO/IEC 1539-1:2004，它是介入了很多新特徵的重大修訂版本。ISO Fortran工作組（ISO/IEC JTC 1/SC 22/WG5）的官方網站有關於Fortran 2003新特徵的詳細總結。

據該文所述，本版本的主要改進包括：

- 增強了的派生類型：參數化派生類型，改進的可訪問性控制，改進的結構構造子和終止器。
- 支持面向對象編程：類型擴展和繼承，多態，動態類型分配，以及類型綁定過程，提供對抽象數據類型的完全支持。
- 改善了數據操縱：可分配的成員（結合了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月通過。它只是一個小改版，略微更正了Fortran 2003的一些問題，並且合併了ISO/IEC TR 19767:2005的子模塊功能。新的功能包括：

- 子模塊，它是用於模塊的補充的結構設施；取代了ISO/IEC TR 19767:2005。
- Coarray Fortran，它是並行執行模型。
- 可伸縮並行構造，用於沒有內部依賴性的循環迭代。
- `CONTIGUOUS`特性，用來指定存儲格局限制。
- `BLOCK`構造，它可以包含具有構造作用域的對象的聲明。
- 遞歸可分配成員，作為在派生類型中遞歸指針的替代者。

對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 TS 29113:2012《進一步的Fotran同C語言的互操作性》。
- ISO/IEC TS 18508:2015《補充的Fortran並行特徵》。

此外的變更和新特徵包括支持：ISO/IEC/IEEE 60559:2011（在IEEE 的最新細小修訂之前的IEEE浮點數標準）、十六進位輸入/輸出、`IMPLICIT NONE`增強和其他變更。

### Fortran 2023

Fortran 2023（ISO/IEC 1539-1:2023）發表於2023年11月，可從ISO獲得。Fortran 2023是對Fortran 2018的細小擴展，它聚焦於更正Fortran 2018的錯誤和缺失。它也增加了一些小特徵，包括條件表達式和實參、簡單過程和枚舉類型功能。增加了基於角度和半圈的三角函數。基於角度的三角函數以前是非常常用的廠商擴展。

## 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的寫法：

```fortranfixed
      PROGRAM HELLO
C     PRINT语句类似WRITE。
C     但是打印到标准输出单元
        PRINT '(A)', 'Hello, world'
        STOP
      END
```

下面是Fortran 90的寫法：

```fortran
 program HelloWorld
   write (*,*) 'Hello, world!'   ! 这是个行内注释
 end program HelloWorld
```

### 最大公約數

下面的FORTRAN 77代碼例子，使用歐幾里德演算法計算兩個數`A`和`B`的最大公約數：

```fortranfixed
*     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
```

下面展示編譯和運行這個程序的結果：

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

### Fortran 90特色示例

下面的程序展示動態記憶體分配和基於陣列的運算，這是Fortran 90介入的兩個特徵。要特別注意的是在操縱陣列時，未出現DO循環和IF/THEN語句，數學運算應用於作為整體的陣列。同樣明顯的是運用了描述性變量名字和普通代碼格式，這符合當代編程風格。這個例子在交互式錄入的數據上計算平均值：

```fortran
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
```

下面展示編譯和運行這個程序的結果：

```console
$ 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編譯器，英特爾公司開發的Fortran編譯器。惠普購買了CVF技術之後不久，將Windows平台上的從CVF 6.6.C之後Fortran編譯器相關權利全部轉售給Intel，它需要微軟Visual Studio外殼的支持才能實現Visual IDE功能。在Intel手上的版本編號從7.0開始至現在。
- Absoft Fortran編譯器
- Open Watcom
- Silverfrost FTN95，個人使用者可免費使用的Fortran 95編譯器套件。支持編譯為Win32或.NET可執行程序，內置名為Plato的IDE，也可通過插件支持Visual Studio，調試器使用SDBG。

Linux作業系統下：

- The Portland Group，現已被Nvidia收購。
- g77，GNU的Fortran 77編譯器，集成在GCC中。
- gfortran，GNU的最新的Fortran編譯器，集成在GCC 4.x及以上版本中，目前支持全部Fortran 95、大部分Fortran 2003和Fortran 2008的功能，以替代g77。
- Intel Fortran編譯器，它支持Linux作業系統。
- Absoft Fortran編譯器
- G95編譯器，開放原始碼的Fortran 95編譯器。
- Sun Studio
- Open64編譯器

## FORTRAN數值庫

幾個著名的Fortran軟體包：

- IMSL — 國際數學和統計庫的數值庫
- 數學核心庫 — Intel數學核心庫
- NAG數值庫 — 數值演算法組的數值庫
- BLAS — 基本線性代數子程序庫
- LAPACK — 線性代數軟體包

## 延伸閱讀

語言標準

- Informally known as FORTRAN 66.
- Also known as ISO 1539–1980, informally known as FORTRAN 77.
- Informally known as Fortran 90.
- Informally known as Fortran 95. There are a further two parts to this standard. Part 1 has been formally adopted by ANSI.
- Informally known as Fortran 2003.

有關標準

其他參考材料

## 外部連結

- ISO/IEC JTC1/SC22/WG5 —the official home of Fortran standards
- Fortran Standards Documents —GFortran standards
- fortran-lang.org (2020).
- History of FORTRAN and Fortran II —Computer History Museum
- Valmer Norrod, et al.: A self-study course in FORTRAN programing—Volume I—textbook , Computer Science Corporation El Segundo, California (April 1970). NASA (N70-25287).
- Valmer Norrod, Sheldom Blecher, and Martha Horton: A self-study course in FORTRAN programing—Volume II—workbook , NASA CR-1478 (April 1970), NASA (N70-25288).
- An introduction to the Fortran programming language, by Reinhold Bader, Nisarg Patel, Leibniz Supercomputing Centre .
- A coarray tutorial

## 基本資料

- 編程范型：多重范型：指令式、過程式、結構化、面向對象、陣列式、泛型
- 發行時間：1957年
- 設計者：約翰·巴科斯
- 開發者：約翰·巴科斯與IBM
- 軟體版本週期：Fortran 2023 (ISO/IEC 1539:2023)
- 軟體版本週期：2023年11月17日
- 類型系統：強類型、靜態
- 軟體實現：GFortran, Intel Fortran編譯器, Nvidia/The Portland Group CUDA Fortran, Silverfrost FTN95, Oracle f95, IBM XL Fortran等
- dialects：F (程式語言)
- 受影響於：Speedcoding
- 施影響於：ALGOL 58, PL/I, BASIC, C, PACT I, MUMPS, Ratfor
- 文件擴展名：`.f`, `.for`, `.f90`