登录后查看更多精彩内容~
您需要 登录 才可以下载或查看,没有帐号?立即注册
x
Fortran95簡介-全文版 By陳鯨太 FORTRAN的演進 FORTRAN的起源,要追溯到1954年IBM公司的一項計畫。由JOHN BACKUS領導的一個小組,嘗試著在IBM704電腦上面發展一套程式,它可以把使用接近數學語言的文字,翻譯成機械語言。這個計畫在剛開始並不被大家看好,但他們在1957年交出了成果,也就是第一套FORTRAN編譯器,FORTRAN語言也就因此誕生了。FORTRAN語言的執行效率普遍的令各界滿意,它證明了這項計畫的可行性,也成為第一個被廣泛使用的高階語言。FORTRAN的名字來自於英文的FORMULATRANSLATOR這兩個字,而這兩個字恰是數學公式翻譯器的意思。 舊版的FORTRAN77是在1978年由美國國家標準局(ANSI)所正式公布的,之後改版有1992年提出的FORTRAN90以及1997年的FORTRAN95,本文是為了FORTRAN 95所撰寫。 編譯器簡介 1、VISUAL FORTRAN VISUAL FORTRAN一開始是起源於MICROSOFT的FORTRANPOWERSTATION 4.0,這套工具後來賣給DIGITAL公司來繼續發展,下一個版本稱為DIGITAL VISUAL FORTRAN 5.0,DIGITAL後來被COMPAQ合併,所以接下來的6.0及6.5版就稱為COMPAQ VISUAL FORTRAN。而COMPAQ目前又跟HP合併,也許下一個版本會稱為HP VISUAL FORTRAN。 VISUAL FORTRAN被整合在一個叫作MICROSOFT VISUAL STUDIO的圖形介面開發環境中,VISUAL STUDIO提供一個統一的使用介面,這個介面包括文書編輯功能,PROJECT的管理、除錯工具等等,所以在使用上其實跟上學期的VISUAL C++滿類似的,同學們上課用過VISUALC++,對VISUAL FORTRAN應該不會陌生。 VISUAL FORTRAN6.5除了完全支援FORTRAN 95的語法外,擴充功能方面提供完整的WINDOWS程式開發工具,專業版還內含IMSL數值程式庫。另外它還可以和VISUAL C++直接互相連結使用,也就是把FORTRAN和C語言的程式碼混合編譯成同一執行檔案。 2、在工作站使用FORTRAN 學校計中工作站也提供FORTRAN COMPILER,使用方式很簡單,只需要在存放FORTRAN檔案的目錄下面輸入下面敘述即可: ccsun33[u8623033/fortran]% f77 filename.for 這個指令使用f77的compiler,其中filename.for就是我們所編寫的FORTRAN程式檔案 ccsun33[u8623033/fortran]% f90 filename.for 這個指令使用f90的compiler 而指令按下enter鍵之後,會把結果COMPILE到a.out這個檔案裡面,我們想要執行這個程式,只要在命令提示字元後打a.out就可以看到執行結果: ccsun33[u8623033/fortran]% a.out 如果在compile的過程中想要把執行檔改成別的檔名,不要每次都變成a.out,那我們可以輸入下列指令 ccsun33 [u8623033/fortran]%f77 filename1.for –o filename2 或者 ccsun33 [u8623033/fortran]%f90 filename1.for –o filename2 則filename2會變成我們的執行檔名字 在COMPILE FORTRAN的時候,我們必需登入學校計中ccsun26~ccsun35的機器才可以使用(學校規定),並且因為軟體總數只有兩套,同時間只有兩個人能可compile。 FORTRAN基本事項 字元集 字元集是指使用FORTRAN的時候,所能使用的所有字元有符號。FORTRAN所能使用的字元集有 1、英文26個字母:大小寫不分 2、數字:0到9 3、22個特殊符號:有冒號、等號、加號、減號、驚嘆號…等等 書面格式 FORTRAN程式碼的寫作格式有兩種,FREE FORMAT(自由格式)以及FIXED FORMAT(固定格式)。簡單來說,FIXED FORMAT是屬於舊式的寫法,它在寫作版面上有很多限制。FREE FORMAT是FORTRAN90之後的新寫法,取消了許多舊的限制。FORTRAN程式碼附加檔名為*.F或*.FOR的檔案,就是指以FIXED FORMAT來寫作的程式,若以*.F90為附加檔名的檔案,就是以FREE FORMAT來寫作的程式。建議現在都應該改用FREE FORMAT來寫作程式。 FIXED FORMAT固定格式之中,規定了程式碼每一行中每個字元欄位的意義。如下表所示: FIXED FORMAT是為了配合早期需要使用打洞卡來輸入程式才發明出來的格式。現在都應該要使用FREE FORMAT來寫作程式。早期的電腦,還沒有使用顯示器作為輸出裝置,不能像現在一樣直接利用鍵盤來修改程式。早期的程式是利用打洞卡片一張一張的記錄下來,再拿給電腦執行。有著打洞卡的淘汰,FIXED FORMAT也沒有必要再繼續使用下去。不過同學們還是可以大概瞭解一下,因為仍有些舊程式是用這種格式來寫作。 FREE FORMATFREE FORMAT基本上允許非常自由的寫作格式,它沒有再去規定每一行的第幾個字元有什麼作用。需要注意的事項只有下面幾點: 1、驚嘆號「!」後面的文字都是註解。 2、每行可以寫作132個字元。(注意! 並不是無限長) 3、行號放在每行程式的最前面。 4、一行程式碼的最後如果是符號&,代表下一行程式會和這一行連接。 例子:sample1.f90 file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image001.png! Free Format program main write(*,*) “hello” ! 列印出hello這個字 write(*,*) & “hello” wri& te(*,*) “hello” end 輸出、輸入及宣告 輸出基本範例 輸出使用write指令,如下例 sample2.f90 file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image002.pngprogram main write(*,*) “hello” stop end FORTRAN程式通常以PROGRAM敘述來開頭,PROGRAM後面還要接一個自訂的程式名稱。這個名稱可以完全自訂,不需要和檔名有任何的關係,這個名字表示「主程式」的名字。我在這裡取名為MAIN,這個名字可以看個人喜好修改。FORTRAN程式最後還要有END這個敘述,表示程式碼寫到這一行結束。 WRITE指令就是作為輸出用,WRITE(*,*)之中兩個星號各有各自的意義,前面的星號表示輸出的位置使用內定值,也就是螢幕,後面的星號表示不特別設定輸出格式。另外,下面三種輸出格式其實會得到一樣的結果: WRITE(*,*) “HELLO” WRITE(6,*) “HELLO” WRITE(UNIT=6, FMT=*) “HELLO” 關於WRITE還有幾點要注意 1、每一次執行write指令之後,會自動換到下一行來準備做下一次的輸出。 2、因為雙引號是用來包裝字串用的,所以想要印出雙引號的時候,要連用兩個雙引號。 例:想要印出 MY NAME IS “CASTER”. 就要下達 WRITE(*,*) “ MY NAME IS “”CASTER””.” 這個敘述 3、FORTRAN90可以使用雙引號或單引號來包裝字串,FORTRAN77標準中只能使用單引號,不過大部份的FORTRAN77還是可以接受雙引號。 範例中還有另一個指令STOP,STOP是終止程式的意思,它可以出現在程式的任何地方,程式執行到這個指令就會中止。除非必要,不要把STOP指令使用在主程式結束之外的其它地方。因為一個程式如果有太多的終止點會容易出錯。STOP指令在這個地方可以省略,因為主程式的程式碼執行完畢後,程式會自動終止。加上這個指令只是為了更明確表示程式到此結束而已。 END是用來包裝程式碼使用的,說明程式碼已經寫作完畢。FORTRAN 90標準中,可以使用下面三種方法來表示程式碼寫作結束,FORTRAN77只能使用第一種方法。 END END PROGRAM END PROGRAM MAIN ! MAIN是主程式的名字 PRINT指令用法大致上和WRITE相同,只是專門針對螢幕作輸出,因此少了指定輸出的能力,它也具有限定輸出格式的功能,其語法如下: PRINT *,”輸出字串” 宣告 1、整數 整數的宣告法很簡單,如下: integer a !宣告a為一個整數,內定範圍為2^32~ -2^32 2、浮點數 real a !宣告a為一個浮點數,預設值為單精確度浮點數 real*4 a !宣告a為一個單精確度浮點數,大小為4byte real*8 a !宣告a為一個雙精確度浮點數,大小為8byte 單精確度可記錄的數值最大為3.4*10^38,最小為-3.4*10^38 3、複數 FORTRAN是少數有提供複數型態的程式語言,宣告方法如下 complex a 設定複數的方法如下: a=(x,y) !x為實部,y為虛部 例如我們設a=(3,8)就表示a是3+8i 範例:sample3.f90 file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image003.pngprogram main complex a,b a=(1.0,1.0) b=(3.0,4.3) write(*,*) “a+b=”,a+b write(*,*) “a-b=”,a-b write(*,*) “a*b=”,a*b write(*,*) “a/b=”,a/b stop end 則執行結果如下 a+b= (4.0,5.3) a-b=(-2.0,-3.3000001) a*b=(-1.3000002,7.3) a/b=(0.2655511,-0.047289926) 4、字元及字串 宣告一個字元的方法如下 CHARACTER a 宣告字串的方法如下 CHARACTER(10)A !宣告A這個字串的最大長度為10 另外使用下面幾種宣告語法也是相同的結果 CHARACTER*10 CHARACTER(LEN=10) CHARACTER*(10) 宣告好之後,我們要給予這個變數一個初始值的方法如下: A=”字串內容” !雙引號在FORTRAN90適用 A=’字串內容’ !單引號在部份FORTRAN77及所有FORTRAN 90都適用 輸入指令 輸入指令的基本語法如下: INTEGER A READ (*,*) A !讀入一個整數,並存到A內 READ (5,*) A !同上 READ(UNIT=5, FMT=*) A !同上 第一個星號表示輸入的來源使用內定的裝置,第二顆星號來源表示不指定輸出格式。鍵盤的輸入位置是5,也就是預設位置,所以可以用星號代替鍵盤代碼。 格式化輸出 格式化輸出入的控制字元非常豐富,但是常用的並不多,在這裡我們只示範幾個比較常用的部份。 A. 關於I WRITE(*,”(I5)”)100 !用5個字元的欄位來輸出一個整數 OUTPUT : _ _ 1 00 WRITE(*,”(I3)”)100000 OUTPUT: * * * 輸出10000需要5個欄位,但是輸出格式只給三個字的欄位,因此印出三顆星號作為警告 WRITE(*,”(I5.4)”) 3 !輸出五個字元欄位,至少輸出4位,不足補0 OUTPUT: _ 0 0 0 3 B. 關於F WRITE(*,”(F9.3)”)123.45 !輸出9個字元欄位,包括小數部份3個位數 OUTPUT: _ _ 1 23 . 4 5 0 C. 關於E WRITE(*,”(E15.7)”) 123.45 ! 用科學計號表示法,輸出15個字元欄位,小數部份佔7位 OUTPUT : _ _ 0 .1 2 3 4 5 0 0 E + 0 3 D. 關於A WRITE (*,”(A10)”)“HELLO” !用10個字元寬度輸出字串 OUTPUT: _ _ _ __ H E L L O WRITE (*,”(A3)”)“HELLO” OUTPUT : H E L E. 關於B WRITE (*,”(B6.5)”)3 !把3變成二進位輸出,字6個字元寬,至少輸出5位 OUTPUT : _ 0 0 01 1 F. 關於X WRITE (*,”(3X)”)20 !輸出前先填3個空白字元 OUTPUT: _ _ _ 20 變數名稱的取名原則 變數名稱的長度限制隨著各家編譯器而有所不同。FORTRAN 77規定至少要支援到6個字元,FORTRAN 90則規定最少要支援到31個字元。變數的名字最好是取成一個有意義的英文單字,這樣可以減少程式寫作時出錯的機會。 IMPLICIT指令 FORTRAN標準中有一項不太好的功能,它的變數並不一定要經過宣告之後才能使用,編譯器會依變數名稱的第一個字母來自動決定這個變數的型態。第1個字母若為I, J, K, L, M, N的變數會被視為整數型態,其它的變數則會被當成浮點數來使用。來看下面範例:SAMPLE4.f90 file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image004.pngPROGRAM MAIN I=11+22 WRITE(*,*) “11+22=”, J STOP END 程式執行結果會得到 11+22=0 這個結果當然是錯誤的,錯誤是出在程式的第3行,原本應該是要輸出變數I,卻不小心打成J,而J仍未設定任何數值,所以會輸出0來。打錯字是寫程式的過程當中最容易發生的錯誤,這一類的錯誤通常很難查覺出來,尤其是在寫作大程式的時候。所以建議在FORTRAN程式中,開始作宣告之前,都加入下面這個敘述: IMPLICIT NONE 加入這個敘述之後,會把內定型態的功能關閉,因此這個範例程式若加入這一行,那麼在COMPILE的過程中就會發生錯誤,我們必需事先宣告所有會使用的變數才可以。 IMPLICIT指令要馬上接在PROGRAM指令的下一行,不能把它放在其它位置。 常數的宣告 常數的宣告有下列兩種方式 A. REAL PI PARAMETER(PI=3.14159) 這個方式先宣告PI是一個浮點數,再宣告它是一個常數,也就是我們所說的圓周率 B. REAL, PARAMETER ::PI=3.14159 這個方式同時宣告PI為浮點數及常數 程式結構 FORTRAN的程式結構應該如下 file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image005.pngPROGRAM xxxx IMPLICIT NONE file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image006.pngINTEGER INT1, INT2 宣告區 REAL REAL1, REAL2 file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image007.pngREAD(*,*)INT1, INT2 程式主體 WRITE (*,*) INT1+INT2 ………………………. STOP END 其中宣告區不可與程式主體交錯。 FLOW CONTROLIF…THEN…ELSE 基本語法如下 file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image008.pngIF(邏輯判斷式) THEN 執行動作1 ELSE 執行動作2 END IF file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image009.pngSAMPLE5.f90 PROGRAM MAIN IMPLICIT NONE REALHIEGHT REALWEIGHT READ(*,*)HEIGHT READ(*,*)WEIGHT IF(WEIGHT > HEIGHT-100) THEN WRITE(*,*)“TOO FAT!” ELSE WRITE(*,*)“UNDER CONTROL” ENDIF STOP END 邏輯運算式 FORTRAN 90的邏輯運算符號共有下列幾種: = = 相等 / = 不相等 > 大於 > = 大於等於 < 小於 < = 小於等於 .AND. 如果兩邊式子都成立,整個條件就成立 .OR. 兩邊的式子只要有一個成立,整個條件就成立 .NOT. 如果後面的式子不成立,整個式子就算成立 .EQV. 兩邊式子的邏輯運算結果相同時,整個式子就成立 .NEQV. 兩邊式子的邏輯運算結果不同時,整個式子就成立 FORTRAN 77要用縮寫來作判斷,不能使用邏輯符號 .EQ. 等於 .NE. 不等於 .GT. 大於 .GE. 大於等於 .LT. 小於 .LE. 小於等於 DO迴圈 DO迴圈基本語法如下: file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image010.pngDO 起始值, 終止值, 累加值 執行程式碼 END DO 舉例如下: file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image011.pngDO I=10, 5, -1 WRITE(*,*)I END DO 在這個程式中,我們設定初始值是I這個變數為10,然後每次減1,一直到I=5為止,因此程式會印出: 10 9 8 7 6 5 DO WHILE … DO WHILE的基本語法如下: file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image012.pngDO WHILE (邏輯運算) 程式碼 END DO 因為跟同學們上學期學過的C語言幾乎一樣,因此在這裡不再多描述。 陣列的宣告與使用 宣告陣列 宣告陣列有下列幾種方法: integer a(10) !宣告a這個陣列有10個元素 integer , dimension(10) :: a ! 同上,另一種作法 而在FORTRAN 77當中,我們必需用下面這種方法 integer a dimension a(10) 請記住在FORTRAN當中的陣列是從1開始算,也就是a(1), a(2)一直到a(10) 使用陣列 我們要使用已經宣告出來的陣列,直接利用其index即可,例如: a(1)=18 也可以利用DATA 這個敘述 INTEGER A(3) DATA A /36, 24, 36/ 在FORTRAN 90中,還可以省略DATA這個敘述 INTEGER:: A(3) = (/36, 26, 36/) 使用這個方式必需注意,括號跟除號之間不能有空格,並且冒號不能省略。 函式 副程式(SUBROUTINE)的使用 寫程式時,可以把某一段常常被使用、具備特定功能的程式碼獨立出來,包裝成副程式,以後只要經由呼叫的CALL指令就可以執行這一段程式碼。 一個包含副程式的FORTRAN程式在結構上大概如下: file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image013.pngPROGRAM MAIN 主程式碼 END SUBROUTINE SUB1() 程式碼 END SUBROUTINE SUBROUTINE SUB2() 程式碼 END SUBROUTINE 主程式不一定要放在程式的最開頭,它可以安排在程式中的任意位置,可以先寫副程式再寫主程式也無妨。副程式的最後一個指令通常是RETURN,表示程式要返回原來呼叫它的地方來繼續執行程式。在主程式內呼叫SUBROUTINE就使用CALL這個指令。 FORTRAN在傳遞參數的時候是使用傳址呼叫(CALL BY REFERENCE),這個意思是說呼叫時所傳遞出去的參數,和副程式中接收的參數,它們會使用相同的記憶體位址來記錄資料。 範例:SAMPLE6.f90 file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image014.pngPROGRAM MAIN IMPLICIT NONE INTEGER:: A=1 WRITE(*,*) “A的初始值是”, A CALLADD(A) WRITE(*,*)“A後來的值是”, A STOP END SUBROUTINE ADD(NUM) IMPLICIT NONE INTEGERNUM NUM= NUM + 1 RETURN END SUBROUTINE 這個程式的輸出會是 A的初始值是1 A後來的值是2 很明顯的看到A的值被SUBROUTINE所改變了!! 自訂函數FUNCTION 自訂函數的運作基本上跟SUBROUTINE非常類似,它也是要經由呼叫才能執行,也可以獨立宣告變數,參數傳遞的方法也如同副程式一樣,它和副程式只有兩點不同: 1、呼叫自訂函數之前必需先宣告。 2、自訂函數執行後會傳回一個數值。 函數的宣告方法如下: REAL , EXTERNAL :: ADD 其中EXTERNAL這個字表示我們宣告的東西是個函數。 FORTRAN 77使用分開的宣告方式: REAL ADD EXTERNAL ADD 範例:SAMPLE7.f90 file:///C:/Users/kingtansin/AppData/Local/Packages/oice_15_974fa576_32c1d314_f21/AC/Temp/msohtmlclip1/01/clip_image015.pngPROGRAM MAIN IMPLICIT NONE REAL, EXTERNAL:: TRIPPLE real:: A=1.38 WRITE (*,*) "A的初始值是", A WRITE (*,*) "呼叫函數",TRIPPLE(A) WRITE(*,*) "A後來的值是", A STOP END REAL FUNCTION TRIPPLE(NUM) IMPLICIT NONE REAL NUM TRIPPLE = NUM * 3 RETURN END 程式的執行結果如下: A的初始值是1.38 呼叫函數 4.14 A後來的值是1.38 我們可以發現,使用了function,讓我們A這個變數不產生改變,而得到我們想要的輸出,而這個也是使用函數的不成文規定:傳遞給函數的參數,只要讀取它的數值就好了,不要去更變它的資料。傳入函數中的參數就是所謂的自變數,而函數傳回的值是應變數。自變數是自由變化的,它的值應該不會在使用函數的過程中被改變,如果想要改變傳入的參數時,最好使用副程式,而不是使用函數來完成工作。這個是寫作函數及副程式時的不成文規定。
|