通過寫「猜數字」遊戲學習 Fortran
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
或*
。 - 只有字元
A
到Z
(大寫字母)、0
到9
(數字)和特殊字元= + - * / ( ) , . $ ' :
和空格能夠使用。
雖然有這些限制,你仍然可以編寫非常有用和有趣的程序。
在 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
將其標識為一個 程序 ,並由最後一行的 END
語句關閉。
定義變數後,程序會提示用戶輸入隨機數種子。Fortran 程序無法從操作系統初始化隨機數生成器,因此你必須始終使用「種子」值和 SRAND
子程序 啟動隨機數生成器。
Fortran 使用 RAND(0)
函數生成 0 到 0.999…… 之間的隨機數。參數 0
告訴 RAND
函數生成一個隨機數。將此隨機數乘以 100 以生成 0 到 99.999…… 之間的數字,然後加 1 得到 1 到 100.999…… 之間的值。INT
函數將結果截斷為整數;因此,變數 NUMBER
就是一個介於 1 到 100 之間的隨機數。
程序會給出提示,然後進入一個循環。Fortran 不支持更現代的編程語言中可用的 while
或 do-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
本文轉載來自 Linux 中國: https://github.com/Linux-CN/archive