标签 Fortran 下的文章

如果你和我一样,在 20 世纪七八十年代使用计算机长大,你可能学过一种常见的个人计算机编程语言,名为 BASIC(全称是 “ 初学者的通用符号指令代码 Beginner's All-purpose Symbolic Instruction Code ”)。那个时期,包括 TRS-80、Apple II 和 IBM PC 在内的每台个人计算机都可以找到 BASIC 实现。当时,我是一个自学的 BASIC 程序员,在尝试了 Apple II 上的 AppleSoft BASIC 后,转向 IBM PC 上的 GW-BASIC,后来在 DOS 上学习了 QuickBASIC。

我通过编写一个示例程序来探索 BASIC 和 FORTRAN 77 中的 FOR 循环,以将数字列表从 1 加到 10。

但是曾经,一种在科学编程领域受欢迎的语言是 FORTRAN(即 “ 公式翻译 FORmula TRANslation ”)。尽管在 1990 年对该语言进行的规范以后,该名称更常见的风格是 “Fortran”。

当我在 1990 年代初作为大学本科物理学生学习物理学时,我利用自己在 BASIC 上的经验学习了 FORTRAN 77。那时我意识到 BASIC 许多概念都来源于 FORTRAN。当然,FORTRAN 和 BASIC 在很多其他方面也存在差异,但我发现了解一点 BASIC 可以帮助我快速学习 FORTRAN 编程。

我想通过使用两种语言编写相同的程序,展示它们之间的一些相似之处。通过编写一个示例程序来探索 BASIC 和 FORTRAN 77 中的 FOR 循环,这个程序将把 1 到 10 之间的数字相加。

Bywater BASIC

BASIC 存在许多种不同的版本,这取决于你的计算机,但该语言总体保持不变。我喜欢的一种 BASIC 版本是 Bywater BASIC,这是一种开源的 BASIC 实现,适用于包括 Linux 和 DOS 在内的不同平台。

要在 FreeDOS 上使用 Bywater BASIC,你必须首先从 FreeDOS 1.3 Bonus CD 中 安装该软件包。然后进入 C: 目录并输入 bwbasic 命令,这将启动 BASIC 解释器。你可以在这个提示符下输入程序:

bwBASIC:

Bywater BASIC 使用较早的 BASIC 编程标准,需要你在每个程序指令上编写一个行号。将行号视为索引。你可以使用行号轻松地引用程序中的任何指令。当你将程序键入 Bywater BASIC 解释器时,请在每个指令前添加行号:

bwBASIC: 10 print "Add the numbers from 1 to 10 ..."
bwBASIC: 20 sum = 0
bwBASIC: 30 for i = 1 to 10
bwBASIC: 40 sum = sum + i
bwBASIC: 50 next i
bwBASIC: 60 print sum
bwBASIC: 70 end

可以使用 list 命令查看你已经输入到解释器中的程序:

bwBASIC: list
10 print "Add the numbers from 1 to 10 ..."
20 sum = 0
30 for i = 1 to 10
40 sum = sum + i
50 next i
60 print sum
70 end

这个简短的程序演示了 BASIC 中的 FOR 循环。 FOR 是任何编程语言中最基本的循环构造,允许你迭代一组值。在 Bywater BASIC 中,FOR 循环的一般语法看起来像这样:

FOR 变量 = 起始值 TO 终止值

在这个示例程序中,指令 for i = 1 to 10 开始一个循环,迭代值为 1 到 10。在每个循环中,变量 i 被设置为新值。

在 BASIC 中,所有到 next 指令前的指令都将作为 FOR 循环的一部分执行。因为你可以将一个 FOR 循环放入另一个 FOR 循环中,Bywater BASIC 使用语法 NEXT 变量 来指定要迭代的循环变量。

在提示符下键入 run 来执行程序:

bwBASIC: run
Add the numbers from 1 to 10 ...
55

Bywater BASIC 被称为 BASIC 解释器,因为只能从 Bywater BASIC 环境中运行程序。这意味着解释器会处理与操作系统的交互的所有繁重工作,因此你的程序不需要自己完成这个工作。 这样做的代价是,程序在解释环境中运行会比它作为编译程序运行慢一些。

FreeBASIC

另一个流行的 BASIC 实现是 FreeBASIC,这是一个开源的 BASIC 编译器,适用于多个平台,包括 Linux 和 DOS。要使用 FreeBASIC,你需要从 FreeDOS 1.3 Bonus CD 安装 FreeBASIC 包,然后进入 C: 目录,你会在这里找到 FreeBASIC 程序。

FreeBASIC 是一个编译器,因此你首先需要创建一个包含程序指令的源文件,然后使用源代码运行编译器以创建一个可运行的程序。我编写了一个类似于“将 1 到 10 的数字相加”的程序版本,将其保存为 BASIC 文件,并命名为 sum.bas

dim sum as integer
dim i as integer
print "Add the numbers from 1 to 10 ..."
sum = 0
for i = 1 to 10
sum = sum + i
next
print sum
end

如果你将这段代码与 Bywater BASIC 版本的程序进行比较,你可能会注意到 FreeBASIC 不需要行号。FreeBASIC 实现了一种更现代的 BASIC 版本,使得编写程序时不需要跟踪行号更容易。

另一个主要的区别是你必须在源代码中定义或声明变量。使用 DIM 指令在 FreeBASIC 中声明变量,例如 dim sum as integer,以定义一个名为 sum 的整数变量。

现在可以在命令行上使用 fbc 编译 BASIC 程序:

C:\DEVEL\FBC> fbc sum.bas

如果你的代码没有任何错误,编译器将生成一个可以运行的程序。例如,我的程序现在称为 sum。运行我的程序将从 1 加到 10:

C:\DEVEL\FBC> sum
Add the numbers from 1 to 10 ...
55

FORTRAN 77

FORTRAN 编程语言类似于旧式和现代 BASIC 之间的混合体。FORTRAN 比 BASIC 更早出现,而 BASIC 显然从 FORTRAN 中汲取灵感,就像后来的 FORTRAN 版本从 BASIC 中获得启示一样。你可以将 FORTRAN 程序以源代码的形式写成文件,但并不需要在每个地方使用行号。但是,FORTRAN 77 在某些指令中使用行号(称为标签),包括 FOR 循环。在 FORTRAN 77 中,FOR 实际上被称为 DO 循环,它执行相同的功能并具有几乎相同的用法。

在 FORTRAN 77 中,DO 循环的语法如下:

DO 行号 变量 = 起始值, 终止值

这种情况是需要行号来指示 DO 循环结束位置的一种情况。你在 BASIC 中使用了 NEXT 指令,但 FORTRAN 需要一个行标签。通常,该行是一个 CONTINUE 指令。

查看这个示例 FORTRAN 程序,了解如何使用 DO 循环来循环一组数字。我将此源文件保存为 sum.f

PROGRAM MAIN
      INTEGER SUM,I
      PRINT *, 'ADD THE NUMBERS FROM 1 TO 10 ...'
      SUM = 0
      DO 10 I = 1, 10
        SUM = SUM + I
   10 CONTINUE
      PRINT *, SUM
      END

在 FORTRAN 中,每个程序都需要以 PROGRAM 指令开始,并指定程序名称。你可能会将此程序命名为 SUM,但随后在程序中不能使用变量 SUM。当我学习 FORTRAN 时,我从 C 编程中借鉴了一些东西,并以 PROGRAM MAIN 开始了我的所有 FORTRAN 程序,做法类似于 C 程序中的 main() 函数,因为我不太可能使用名为 MAIN 的变量。

FORTRAN 中的 DO 循环类似于 BASIC 中的 FOR 循环。它迭代从 1 到 10 的值。变量 I 在每次循环中获取新值。这样可以将 1 到 10 的每个数字相加,并在完成时打印总和。

你可以在每个平台上找到适合的 FORTRAN 编译器,包括 Linux 和 DOS。FreeDOS 1.3 的 Bonus CD 中包括 OpenWatcom FORTRAN 编译器。在 Linux 上,你可能需要安装一个包来安装 GNU Fortran 支持(在 GNU 编译器集合(GCC)中)。在 Fedora Linux 上,你可以使用以下命令添加 GNU Fortran 支持:

$ sudo dnf install gcc-gfortran

然后你可以使用以下命令编译 sum.f 并运行程序:

$ gfortran -o sum sum.f
$ ./sum
ADD THE NUMBERS FROM 1 TO 10 ...
55

一点不同之处

我发现 FORTRAN 和 BASIC 非常相似,但也存在一些不同之处。这些语言的核心是不同的,但如果你了解一些 BASIC,你可以学习 FORTRAN,同样,如果你了解一些 FORTRAN,你也可以学习 BASIC。

如果你想探索这两种语言,有几点需要注意:

  • FORTRAN 77 使用全大写,但后来的 FORTRAN 版本允许大小写混用,只要对变量、函数和子程序使用相同的大小写。大多数 BASIC 实现都不区分大小写,这意味着你可以自由地混合大小写字母。
  • 有许多不同版本的 BASIC,但它们通常做同样的事情。如果你学会了一种 BASIC 实现方式,很容易学会另一种。注意 BASIC 解释器或编译器的警告或错误信息,查阅手册了解差异。
  • 某些 BASIC 实现需要使用行号,例如 Bywater BASIC 和 GW-BASIC。更现代的 BASIC 版本允许你编写不使用行号的程序。FreeBASIC 需要使用 -lang 废弃选项编译带有行号的程序。

(题图:MJ/dba28597-dd62-4ffe-bb4a-e38874a65239)


via: https://opensource.com/article/23/4/basic-vs-fortran-77

作者:Jim Hall 选题:lkxed 译者:ChatGPT 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出

Fortran 是在打孔卡时代编写的语言,因此它的语法非常有限。但你仍然可以用它编写有用和有趣的程序。

 title=

Fortran 77 是我学习的第一门编译型编程语言。一开始时,我自学了如何在 Apple II 上用 BASIC 编写程序,后来又学会在 DOS 上用 QBasic 编写程序。但是当我去大学攻读物理学时,我又学习了 Fortran

Fortran 曾经在科学计算中很常见。曾几何时,所有计算机系统都有一个 Fortran 编译器。Fortran 曾经像今天的 Python 一样无处不在。因此,如果你是像我这样的物理学专业学生,在 1990 年代工作,那你肯定学习了 Fortran。

我一直认为 Fortran 与 BASIC 有点相似,所以每当我需要编写一个简短程序,来分析实验室数据或执行其他一些数值分析时,我都会很快想到 Fortran。我在空闲时用 Fortran 编写了一个“猜数字”游戏,其中计算机会在 1 到 100 之间选择一个数字,并让我猜这个数字。程序会一直循环,直到我猜对了为止。

“猜数字”程序练习了编程语言中的几个概念:如何为变量赋值、如何编写语句以及如何执行条件判断和循环。这是学习新编程语言时一个很好的的实践案例。

Fortran 编程基础

虽然 Fortran 这些年来一直在更新,但我最熟悉的还是 Fortran 77,这是我多年前学习的实现版本。Fortran 是程序员还在打孔卡上编程的年代创建的,因此“经典” Fortran 仅限于处理可以放在打孔卡上的数据。这意味着你只能编写符合以下限制条件的经典 Fortran 程序(LCTT 译注:后来的 Fortran 95 等版本已经对这些限制做了很大的改进,如有兴趣建议直接学习新版):

  • 每张卡只允许一行源代码。
  • 仅识别第 1-72 列(最后八列,73-80,保留给卡片分类器)。
  • 行号(“标签”)位于第 1-5 列。
  • 程序语句在第 7-72 列。
  • 要表示跨行,请在第 6 列中输入一个连续字符(通常是 +)。
  • 要创建注释行,请在第 1 列中输入 C*
  • 只有字符 AZ(大写字母)、09(数字)和特殊字符 = + - * / ( ) , . $ ' : 和空格能够使用。

虽然有这些限制,你仍然可以编写非常有用和有趣的程序。

在 Fortran 中猜数字

通过编写“猜数字”游戏来探索 Fortran。这是我的实现代码:

CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
C     PROGRAM TO GUESS A NUMBER 1-100
CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC
      PROGRAM GUESSNUM
      INTEGER SEED, NUMBER, GUESS

      PRINT *, 'ENTER A RANDOM NUMBER SEED'
      READ *, SEED
      CALL SRAND(SEED)

      NUMBER = INT( RAND(0) * 100 + 1 )

      PRINT *, 'GUESS A NUMBER BETWEEN 1 AND 100'
 10   READ *, GUESS

      IF (GUESS.LT.NUMBER) THEN
         PRINT *, 'TOO LOW'
      ELSE IF (GUESS.GT.NUMBER) THEN
         PRINT *, 'TOO HIGH'
      ENDIF

      IF (GUESS.NE.NUMBER) GOTO 10

      PRINT *, 'THATS RIGHT!'
      END

如果你熟悉其他编程语言,你大概可以通过阅读源代码来弄清楚这个程序在做什么。前三行是注释块,表示程序的功能。第四行 PROGRAM GUESSNUM 将其标识为一个 程序 program ,并由最后一行的 END 语句关闭。

定义变量后,程序会提示用户输入随机数种子。Fortran 程序无法从操作系统初始化随机数生成器,因此你必须始终使用“种子”值和 SRAND 子程序 subroutine 启动随机数生成器。

Fortran 使用 RAND(0) 函数生成 0 到 0.999…… 之间的随机数。参数 0 告诉 RAND 函数生成一个随机数。将此随机数乘以 100 以生成 0 到 99.999…… 之间的数字,然后加 1 得到 1 到 100.999…… 之间的值。INT 函数将结果截断为整数;因此,变量 NUMBER 就是一个介于 1 到 100 之间的随机数。

程序会给出提示,然后进入一个循环。Fortran 不支持更现代的编程语言中可用的 whiledo-while 循环(LCTT 译注:Fortran 95 等新版支持,也因此在一定程度上减少了 GOTO 的使用)。相反,你必须使用标签(行号)和 GOTO 语句来构建自己的循环。这就是 READ 语句有一个行号的原因:你可以在循环末尾使用 GOTO 跳转到此标签。

穿孔卡片没有 <(小于)和 >(大于)符号,因此 Fortran 采用了另一种语法来进行值比较。要测试一个值是否小于另一个值,请使用 .LT.(小于)。要测试一个值是否大于另一个值,请使用 .GT.(大于)。等于和不等于分别是 .EQ..NE.

在每次循环中,程序都会验证用户的猜测值。如果用户的猜测值小于随机数,程序打印 TOO LOW,如果猜测大于随机数,程序打印 TOO HIGH。循环会一直持续,直到用户的猜测值等于目标随机数为止。

当循环退出时,程序打印 THATS RIGHT! 并立即结束运行。

$ gfortran -Wall -o guess guess.f

$ ./guess
 ENTER A RANDOM NUMBER SEED
93759
 GUESS A NUMBER BETWEEN 1 AND 100
50
 TOO LOW
80
 TOO HIGH
60
 TOO LOW
70
 TOO LOW
75
 TOO HIGH
73
 TOO LOW
74
 THATS RIGHT!

每次运行程序时,用户都需要输入不同的随机数种子。如果你总是输入相同的种子,程序给出的随机数也会一直不变。

在其他语言中尝试

在学习一门新的编程语言时,这个“猜数字”游戏是一个很好的入门程序,因为它以非常简单的方式练习了几个常见的编程概念。通过用不同的编程语言实现这个简单的游戏,你可以弄清一些核心概念以及比较每种语言的细节。

你有最喜欢的编程语言吗?如何用你最喜欢的语言来编写“猜数字”游戏?跟随本系列文章来查看你可能感兴趣的其他编程语言示例吧。


via: https://opensource.com/article/21/1/fortran

作者:Jim Hall 选题:lujun9972 译者:unigeorge 校对:wxy

本文由 LCTT 原创编译,Linux中国 荣誉推出