当前位置:首页 >> 语文 >>

Fortran讲义


Fortran

發展簡史
? ?

?

?

?

?

?

1954:IBM 在 IBM 704 上發展 1957:IBM發表,Fortran → Formula Translator 1966:American Stan

dards Association 制訂 Fortran 66 ? 鑑於各家編輯器無法相容,故統一標準 ? American Standards Association:美國國家標準局(ANSI)的前身 1978:ANSI 公布 Fortran 77 標準 ? 刪去部分內容,新增邏輯與輸出入方面的功能 1992:國際標準組織 ISO 公布 Fortran 90 標準 ? 與 77 版本差異大 ? 加入物件導向、提供指標與加強陣列功能、自由格式寫作 1997:國際標準組織 ISO 公布 Fortran 95 標準 ? 加強平行運算 Fortran 200x

書面格式
?

Fixed Format是舊式的寫法,有較多的限制,

Fixed Format副檔名用 *.F 或 *.FOR 。
?

Free Format則是Fortran 90以後新增的作法,以副檔名 做為區隔,Free Format使用 *.F90。

?

Fixed Format(固定格式)
字元位置意義: 第 1 字元:如果是字母 C 或 c 或是星號 *,本行視為註解 第 1-5 字元:空白,或是一組數字為本行程式的代號 第 6 字元:放上 0 以外的字元,表示為接續上一行程式碼 第 7-72 字元:程式碼寫作區域 第 73 字元以後:不使用,編輯器會忽略,有些則發出錯誤訊息
?

程式碼之間多餘的空格不具意義,僅作分隔與方便閱讀 配合打孔卡片所發展,Fortran 90之後可採用Free Format

?

例如:

1:C FIXED FORMAT 2: PROGRAM FIXED 3: READ (*,10) A,B 4: 10 FORMAT (F5.1,F5.1) 5: SUM = A + B 6: WRITE (*,20) 7: +SUM 8: 20 FORMAT (1X,F6.1) 9: END

?

Free Format(自由格式)
? ? ? ? ? ?

Fortran 90 開始使用,附加檔名為 *.F90 不再規定第幾字元有何特定用途 驚嘆號「!」後都是註解 每行可以寫作 132 字元 如有行號放在每行最前面 程式連接符號改為「&」,放在每行程式碼最前或最後,表連結 前一行或是下一行

例如: 1:! free format 2: program free 3: read (*,10) a,b 4:10 format (f5.1,f5.1) 5: sum=a+b 6: write (*,20) & 7: sum 8:20 format (1x,f6.1) 9: end
?

輸出入指令
?

WRITE
? ?

write(*,*) "Hello" "*"星號意義:
前者代表使用預設輸出裝置(一般即為螢幕) 後者代表不特別設定輸出格式

嚴謹用法: write(UNIT=*,FMT=*) "Hello" ! 使用預設輸出裝置,不設定特別格式 write(6,*) "Hello" ! 使用螢幕輸出,不設定特別格式 write(UNIT=6,FMT=*) “Hello” ! 最嚴謹的寫法 輸出字串若包含有單或雙引號,請參考字串宣告 格式化請參見FORMAT

?

PRINT
print *, "Hello" print指令沒有指定輸出裝置的能力,只能針對螢幕輸出

?

READ

read (*,*) a 讓使用者能透過鍵盤輸入變數內容 "*"星號意義: ? 前者代表使用預設輸入裝置(一般為鍵盤) ? 後者代表不指定輸入格式 嚴謹用法: read(UNIT=*,FMT=*) "Hello" ! 使用預設輸入裝置,不指定輸入格式 read(5,*) "Hello" ! 使用鍵盤輸入,不指定輸入格式 read(UNIT=5,FMT=*) "Hello" ! 最嚴謹的寫法 注意事項: 輸入字串無頇加上雙引號,但字串中若有空格或逗號,將被視為兩筆 資料,比如: ? read (*,*) a, b 若輸入 Happy Birthday,則a="Happy","b="Birthday" ? read (*,*) a 若輸入 Happy Birthday,則a="Happy"

?

FORMAT

a = 12.3456 write (*,*) a write (*,100) a 100 format(f5.2) 則前者輸出結果為「12.3456」,後者為「12.34」 f5.1代表使用5個字元長度顯示浮點數,其中小數佔1位

1. 簡化的用法1:將輸出格式寫在write指令中 write (*,"(1x,f5.2)") a 優點: 減少程式行數及行號使用 容易閱讀(不用另找行號、FORMAT) 缺點: 格式複雜時,程式碼混亂 格式設定相同時,無法重複利用

2. 簡化的用法2:
不同格式控制指令,(1x,f5.2)可以移去逗號簡化成format (1xf5.2) 重複相同格式(a3,a3)不可以簡化成(a3a3),改用format (2a3) 若有不同格式時,如(1xf5.2 , 1xf5.2 , 1xf5.2)則改用format (3(1xf5.2)) 3. 字串可以直接寫入格式內: write (*,"(a4,I1)") "1+2=",1+2 write (*,"('1+2=',I1)") 1+2 輸出均為 1+2=3 。上例中單雙引號混用,但F77只用使用單引號: write (*,'(''1+2='',I1)') 1+2

4. 使用字串變數做為格式條件,如: character(len=10) fmtstring fmtstring = "(f5.1)" write (*,fmtstring) 123.4 好處在於,若執行階段輸出變數超過5個字元,可經由如:fmtstring(3:3)=“8”, 使得格式成為(f8.1),以容納更大的數字
5. 常見錯誤: 變數型態與格式型態不符:比如變數為整數123,卻給定字串型態A3 早期應用在印表機輸出時,第一個字元被做為控制字元,所以早期程式設計師習 慣上每一行最前面預留一個空白(1X),但多數編輯器已經取消這個設計 6. 通常設計師建議,不要將format集中排列,如此不利於搜尋。最好將format直接 放在write之下、甚至用上述寫入write中。(但有些format被重複使用,所以非每 行write都有format伴隨)

變數型態
?

基本概念
以整數為例: integer a "a"為自己取的變數名稱,代表一個儲存整數的空間位置,稱為變數 宣告後透過該名稱來給予或提供變數內容,如: 1. program example 2. integer a, b 3. a = 3 ! 將a變數設定為3 4. b = a ** 2 ! 將b變數設定為a**2,即3**2 5. print *, "a=", a ! 寫出a的內容 6. print *, "b=", b ! 寫出b的內容 7. stop 8. end example

執行結果 a= b= 3 9

? 使用注意: 等號意義代表將左邊變數的內容,設定成右邊的數值或計算結果 ? 名稱命名等原則及注意事項,請參考變數宣告

?

整數型態 (INTEGERAL)
integer a
1. 使用注意: ? 計算結果無條件捨去小數部分 ← 常見錯誤! 如:a=3/2 → a=1 、a=1/2 → a=0 ? 宣告未指定長度時,通常表示為長整數 2.長整數 - 使用4位元組(4 bytes, 32 bits) integer(kind=4) a ! F90新增作法 integer(4) b ! INTEGER*4 c ! F77傳統作法 可儲存範圍:-2,147,483,648 ~ +2,147,483,647

3. 短整數 - 使用2位元組(2 bytes, 16 bits) integer(kind=2) a ! F90新增作法 integer(2) b ! INTEGER*2 c ! F77傳統作法 可儲存範圍:-32,768 ~ +32,767 4. 部分編譯器支援 - 使用1位元組(1 bytes, 8 bits) integer(kind=1) a ! F90新增作法 integer(1) b ! INTEGER*1 c ! F77傳統作法 可儲存範圍:-128 ~ +127

?

浮點數型態 (REAL)
real a
未指定kind值時,通常宣告為單精準度(kind=4)
1. 單精準度 - 使用4位元組(4 bytes, 32 bits) real(kind=4) a ! F90新增作法 real(4) b !

REAL*4

c ! F77傳統作法

可表示範圍(PC):±1.18*10-38 ~ ±3.40*1038 單精準度有效位數為6-7位,注意可能有以下問題: a = 1000000. + 0.1 → a = 1000000. ← 常見錯誤,大數加小數!

2. 雙精準度 - 使用4位元組(8 bytes, 64 bits) real(kind=8) a ! F90新增作法 real(8) b ! REAL*8 c ! F77傳統作法 可表示範圍(PC):±2.23*10-308 ~ ±1.79*10308 雙精準度有效位數為15位 3. 使用注意: 常數部分請加上".0",如3 → 3.0(只加"."亦可) real a ? a= 1.5+3./2. → a= 3.0 (3.與2.被視為浮點數) ? a= 1.5+3/2 → a= 2.5 (3/2視為整數,小數無條件捨去)← 常見錯誤! 雙精準度(REAL*8),常數請加上"d0",如3 → 3.d0 ← 常見 忽略! 或採用 a = 1.0_4 表示 kind = 4 a = 1.0_8 表示 kind = 8 可用科學記號表示法,如 ? 10,000,000,000 = 1E10 (1D10 代表雙精準度) ? 0.0000000001 = 1E-10 (1D-10代表雙精準度)

?

複數型態 (COMPLEX)

complex a
(複數由實部與虛部組成,a=x+yi,x 為實部、y 為虛部,皆為實數型態) 1. 使用注意: ? 設定數值 a = (x,y) ! a = x + yi ,若x=1.5,y=2.5,a=1.5 + 2.5i a = (1.5,2.5) ! a = 1.5 + 2.5i a = 1.5 ! a = 1.5 + 0i 2. 單精準度 - 使用兩個單精準浮點數 complex(kind=4) a ! F90新增作法 complex(4) b ! COMPLEX*8 c ! F77傳統作法 3. 雙精準度 - 使用兩個雙精準浮點數 complex(kind=8) a ! F90新增作法 complex(8) b ! COMPLEX*16 c ! F77傳統作法

?

字元與字串 (CHARACTER)
character a (此例僅能儲存一個字元)
1. 長度超過一個字元時,需指定長度,如需十個字元長度時: character(len=10) a ! F90新增作法 character(10) b ! CHARACTER*10 c ! F77傳統作法 CHARACTER*(10) d !

2. 使用注意: ? 設定字串變數: a = "Hello" ! F90使用單或雙引號來包裝字串 b = 'Hello' ! F77使用單引號來包裝字串 c = "That's right" ! 使用雙引號中,有單引號不受影響 d = ?That??s right? ! 使用單引號,字串又包含單引號時,請連續使用 兩個單引號 e = “”“Hello”“” ! 使用雙引號,字串又包含雙引號時,請連續使用兩 個雙引號,本例輸出為"Hello" ? 設定部分字串: string(1:4) = "Good" ! 指定1-4字元 string(5:5) = " " ! 指定第5字元 string(6:) = "morning" ! 指定第6個字元以後的字串 使用 // 連接兩字串:string_a = string_b // string_c 副程序中宣告為不定長度(依呼叫端長度決定)

?

邏輯變數 (LOGICAL)

logical a
1. 使用注意: 設定邏輯變數: a = .true. ! 設定為「真」 a = .false. ! 設定為「假」 使用 WRITE 輸出時,僅顯示 T 或 F 但實務上邏輯變數很少用於輸出 2. 通常不指定使用空間大小,由編輯器自行決定,最少只需1個位元(1 bit) 若指定使用4個位元組時(4 bytes, 32 bits) logical(kind=4) a ! F90新增作法 LOGICAL*4 b ! F77傳統作法 LOGICAL(4) c ! F77傳統作法 (也可使用2個位元組,將上例4換為2即可)

?

自訂資料型態 (TYPE) - F90新增
舉例來說,若程式中需記錄一個人的姓名、身高、體重、血型,則 需要宣告四個變數,透過自訂型態,我們可以訂定一個「人員基本 資料」的資料型態,其中將包含上述的各項資料型態,該資料型態 變數使用起來就像是Visual Basic的物件。以下舉實例說明:

! 建立名稱為person的自訂資料型態 type :: person character(len=25) :: name ! 記錄姓名 integer(kind=2) :: length ! 記錄身高 integer(kind=2) :: weight ! 記錄體重 character(len=2) :: blood ! 記錄血型 end type person ! 自訂資料型態結束,本例中person型態包括了四個元素 type(person) :: a ! 宣告一個person型態的變數 read(*,*) a%name ! 讀取變數a的姓名資料,變數與元素間以%隔開 write(*,*) a%name ! 列印變數a的姓名資料 a = person("Frank",172,75,"O") ! 直接設定所有資料

?

KIND的應用 - F90新增

宣告INTEGER與REAL時,KIND值將影響可儲存範圍與有效位數,以PC來說: integer(kind=1):-128 ~ +127 integer(kind=2):-32,768 ~ +32,767 integer(kind=4):-2,147,483,648 ~ +2,147,483,647 real(kind=4):±1.18*10-38 ~ ±3.40*1038 ,有效6-7位 real(kind=8):±2.23*10-308 ~ ±1.79*10308 ,有效15位 以下兩個函數可以判斷要記錄數值值域範圍所需的kind值。一般雖無頇使用,但 若程式有需要在不同電腦系統間移植,由於可儲存位數的差異,若能依實際需 要查詢該系統的kind值,可使程式維持正確性

? SELECTED_INT_KIND(n) 傳回需要記錄 n 位整數時,所應宣告的kind值 傳回 -1 時,表示無法提供該數值值域範圍

? SELECTED_REAL_KIND(n,e) 傳回需要記錄 n 位有效位數、指數達到 e 位的浮點數所需kind值 傳回 -1 表示無法滿足所要求有效位數 傳回 -2 表示無法滿足所要求指數範圍 傳回 -3 表示兩者都無法滿足 舉例: integer, parameter :: short_int = SELECTED_INT_KIND(3) integer, parameter :: long_real = SELECTED_REAL_KIND(9,30) integer(kind = short_int) :: a = 172 real(kind = long_real) :: b = 1.23456789D25

變數宣告
? 變數名稱命名原則注意: 名稱可使用英文字母a-z、底線_、數字0-9(首字需為英文字母) 變數名稱長度,F77規定至少支援1-6個字元,F90支援1-31個字元 雖未規定,但建議不要與執行指令相同(比如PRINT) 建議取有意義的英文單字,增加程式可讀性並減少出錯的機會

? 一般變數宣告請參閱:變數型態

? 注意內定型態的影響: 變數不一定需經過宣告才能使用,未經過宣告之變數,依變數第一個字母 決定型態 未經宣告下,第一個字母 i,j,k,l,m,n 的變數將被視為整數型態,其他的則為 浮點數;但可透過IMPLICIT來改變此預設狀態 建議所有變數仍應宣告,以瞭解記憶體使用情況並能降低人為錯誤發生 可配合IMPLICIT NONE指令限制所有變數需經宣告才能使用,以降低人為 錯誤發生,比如變數 i 打成 j ? 可用parameter宣告變數為常數,以減少錯誤並增加執行速度 ? equivalence則是在特殊情況下可減少記憶體的浪費以及增加速度 ?宣告結構注意: ? 宣告的位置要在可執行敘述之前,在數值計算或是輸出入指令後就不能 再宣告 ? DATA也是宣告的一部份,也只能放在執行指令前 ? 通常program後接著implicit,然後宣告變數,最後是DATA

?

IMPLICIT

未經宣告變數,編輯器會以其第一個字母決定型態,此稱為「內定型態」。 預設的狀況是,第一個字母 i,j,k,l,m,n 的變數將被視為整數型態,其他的則為 浮點數。 IMPLICIT可以用來改變與關閉內定型態。 1. 使用方式:

implicit integer(A,B,C) ! A,B,C開頭變數視為整數
implicit integer(A-D,X,Y) ! A-D,X,Y開頭變數視為整數 implicit real(L-P) implicit none ! L-P開頭變數視為實數 ! 關閉此項服務,所有變數皆需經過宣告

2. 一個程式單元可以有一個以上 IMPLICIT 敘述,但是所有 IMPLICIT 敘述 必頇在該程式單位所有其他宣告敘述之前才行。通常就是在program指令 下一行。 3. 如果設定 IMPLICIT NONE,則所有使用者定義的名稱都必頇宣告其型態, 未定義型態的名稱會產生編譯時期錯誤。也就是說,會強迫你宣告所使 用到的每一個變數名稱。強烈建議初學者使用,因為助教實在太常遇到 同學把變數名稱給拼錯或是型態錯誤(比如i,j,k,l,m,n開頭的變數預設為 整數)。 4. 一個程式單元只能有一個 IMPLICIT NONE 敘述,也不能有其他的 IMPLICIT 敘述。

?

給定初值.DATA

變數宣告後,可利用等號來給定初值,如: real pi pi = 3.14159 但若要給初值的變數很多,程式便顯得雜亂,請參考: ? 利用 DATA/.../ 指令,依序給定變數初值 real a, b complex c character(10) string data a, b, c, string /1.0, 2.0, (3.0,4.0), 'Hello'/ 則依順序,a=1.0 ,b=2.0 ,c=(3.0,4.0) ,string = 'Hello' 使用在陣列變數中,更顯其方便: real a(4) data a /1.0 , 2.0 , 3.0 , 4.0/

? F90可以將宣告與初值寫在同一行程式碼中:
real :: pi = 3.14159 integer :: count = 0 此時冒號不可省略 ? 給定整數資料時,可以2、8、16進位方式 若要給定28(十進位),可採用: a = B"11100" ! B 代表二進位 (Binary) - 0,1 a = O"34" a = Z"1C" ! O 代表八進位 (Octal) - 0,1,2,3,4,5,6,7 ! Z 代表十六進位 - 0,1,2,3,4,5,6,7,8,9,A,B,C,D,E

?

PARAMETER

PARAMETER (pi=3.14159) 可將變數pi視為常數使用,通常目的在簡化程式碼、減少錯誤、方便修改以及 增加可讀性 area = pi * radius**2 可讀性較 area = 3.14159 * radius**2 更好 若需將3.14159改為其他數字時,只需修改如:PARAMETER (pi=3.14) 1. 注意事項: ? 數值只能設定一次 ? 在程式碼中不可去改變常數的內容 2. 將PARAMETER (pi=3.14159)改為一般變數pi=3.14159,程式仍可執行,但 設定為常數後: ? 若程式碼有修改該常數內容時,編譯階段會有錯誤訊息 ? 若變數內容在執行階段不會改變,改為常數將可增加執行速度 3. F90中,變數與常數宣告可以寫入同一行: real, parameter :: pi=3.14159 ! pi前的冒號不能省略 冒號在告訴編輯器,宣告型態與設定已經完畢,冒號後開始給定變數名稱

?

EQUIVALENCE(等位宣告)

integer a,b equivalence (a,b) 則變數 a,b 將使用同一個記憶體空間,只是有兩個名稱 1. 用途之一: ? 程式中的暫時變數,有時程式需要一些暫時使用的資料變數,通常設 計師會宣告一個temp變數,但如此程式可讀性降低,但若每一個都各 自宣告又浪費記憶體空間,此時可以利用equivalence,讓多個暫存變數 使用同一記憶體空間。 比如: integer temp_count, temp_record equivalence (temp_count, temp_record) 需注意兩個暫存變數未被同時使用,否則產生錯誤

?

2. 用途之二: ? ? 在陣列資料中,如某一位置經常被使用,則可以利用 equivalence提昇效率。 比如: equivalence (array(2,3,4), a) 程式中需使用 array(2,3,4) 的地方改以 a 代替,除了精簡版面, 系統在陣列的處理上需從陣列起始位置換算array(2,3,4)的記 憶體位置,而 a 則可以直接獲得,可提昇效率

流程控制與邏輯運算
?

The Logical IF Statement
IF (logical expression) statement

?

The Arithmetic IF Statement
IF (arithmetic expression) num1,num2,num3 expression < 0 then goto num1 expression = 0 then goto num2 expression > 0 then goto num3

?

The IF-ENDIF Statement
IF (<logical expression>) THEN ... ... (statement group) ... ENDIF ...

?

The ELSE Statement
The IF-ENDIF Statement IF (<condition>) THEN ... ... (statement group 1) ... ENDIF IF (<opposite condition >) THEN ... ... (statement group 2) ... ENDIF The ELSE Statement IF (<condition>) THEN ... ... statement to be executed if <condition> is .TRUE. ... ELSE ... ... statement to be executed if <condition> is .FALSE. ... ENDIF

?

The ELSE-IF Statement
IF (<logical expression 1>) THEN ... ... (statement group 1) ... ELSEIF (<logical expression 2>) THEN ... ... (statement group 2) ... ELSEIF (<logical expression 3>) THEN ... ... (statement group 3) ... ELSEIF (<logical expression n>) THEN ... ... (statement group n) ... ELSE ... ... (all false statement group) ... ENDIF

?

Nesting IF-ENDIF Structures
IF (<logical expression-1>) THEN
... ... IF (<logical expression-2>) THEN ... ... ENDIF ... ... ENDIF

?

Logical Expression
?

?

LOGICAL Type The <condition>s are logical expressions, which can only have values .TRUE. and .FALSE. Logical expressions
? ? ? ? ? ? ?

Relational expressions (comparisons) Logical variable .NOT. logical expressions (logical complement) Logical expressions .AND. Logical expressions (logical conjunction) Logical expressions .OR. Logical expressions (logical disjunction) Logical expressions .EQV. Logical expressions (logical equivalence) Logical expressions .NEQV. Logical expressions (logical differ)

?

Relational expressions compare two numeric or character quantities, and have the following form: quantity <relation> quantity

?

Relational operator (quantity <relation> quantity)
F77使用縮寫 .EQ. .NE. .LT. F90可用符號 == /= < 代表意義 = equal to ≠ not equal to < less than

.GT.
.LE. .GE.

>
<= >=

> greater than
≦ less than or equal to ≧ greater than or equal to

?

Logical operators
B
True False

A
True True

.NOT. A
False False

A .AND. B
True False

A .OR. B
True True

A .EQV. B
True False

A .NEQV. B
False True

False

True

True

False

True

False

True

False

False

True

False

False

True

False

?

浮點數與字元的邏輯運算
?

浮點數 Example:
a = (3.**0.5)** 2 b = 3. -> b - a 不會等於 0.0 ,(b-a .EQ. 0.0) is .FALSE. ? 理論上 b - a 應等於 0.0 ,但受計算浮點數 a 時有效位數的影響, (3.**0.5)即產生誤差,再平方後只是接近 3. 的數字但並不等於 3. ,所 以 (b-a .EQ. 0) 邏輯值為 .FALSE. ? 將 a 值做螢幕輸出,得到 a = 0.0?可能是輸出格式的限制,所見為近 似值(如已四捨五入) ? 一般會採絕對或相對誤差來判斷,如 if (abs(b-a) .LE. 0.000001) then ... 或 if (abs(b-a)/b .LE. 0.000001) then ... 註:abs函數可以傳回絕對值 ? 上例中,若改為 a = (4.**0.5)** 4 - 3. ,因 (4.**0.5) 得到 2. 沒有有效位 數不足的問題,所以 b - a 值會等於 0.0
?

?

字元的比較:
?

字元可以比較大小,依其ASCII編碼順序
'a' < 'b' ,∵ ascii(a)=97,ascii(b)=98 'A' < 'a' ,∵ ascii(A)=65,ascii(a)=97

?

! ascii非內建函數,只是為了表達方便,請參考ichar 字串比較時,則依字母順序一一比較下來 'abcd' < 'axyz'

?

SELECT CASE

F90新增,但幾乎所有F77編譯器都有支援 SELECT CASE (variable) CASE (value-1) ... ... (statement group 1) ... CASE (value-2) ... ... (statement group 2) ... CASE (value-3) ... ... (statement group 3) ... CASE DEFAULT ... ... (all false statement group) ... END SELECT

?

補充說明:
? ?

case default 區段非必要 CASE(value) 中,(value)可用(value1:value2),如 1:5 表示當 1≦變數 ≦5 時執行該區段 可取代IF-ELSE IF,但只接受整數、字元、邏輯變數,不能使用浮 點數和複數 CASE中的數值,必頇是常數

?

?

?

GOTO

在F77以前做為流程與迴圈控制,但由於容易造成程式結構混亂、降低可讀 性、並產生錯誤,所以不建議使用。 Example 1: (IF-ELSE) if (a .GE. 60) then goto 100 print *, "pass!" goto 200 100 print *, " 200 stop Example 2: (LOOP) sum = 0 count = 1 100 if (count .GT. 10) then goto 200 sum = sum + count count = count + 1 goto 100 200 print *, sum stop

?

PAUSE.CONTINUE.STOP
?

?

?

PAUSE 程式執行至此,會暫停,並等待使用者按下 ENTER 鍵後繼續,在有大量資 料作螢幕輸出時使用 CONTINUE 表示「繼續往下執行」,而就算沒有這行,也會繼續啊... 在F77中,通常只是為了方便閱讀程式碼,比如與GOTO配合做迴圈使用時 STOP 結束程式執行,比如在 IF 中,當某條件成立或不成立,程式就必頇中斷 使用此指令要小心,以免反致程式結構混亂,不該終止被終止

迴圈
?

The CONTINUE and GOTO statements
? ?

由於 GOTO 的使用不當將造成程式結構混亂,且其閱讀性差,從 Fortran 77 開始,已經不建議使用 GOTO ,而利用 DO 指令。 利用GOTO強制程式回到特定指令行,形成迴圈: ... statement preceding loop ... <label> CONTINUE ... loop body ... GOTO <label> ... statement following loop ...

?

loop body 需加入迴圈終止判斷,Conditional termination of loop execution
?
?

IF {<exit condition>} GOTO <exit label> IF {<exit condition>} THEN ... statement to be executed just prior ... to leaving the loop at this point. GOTO <exit label> ENDIF
<index-variable> = <initial-value> * .... top of indexed loop .... 100 CONTINUE IF (<index-variable> .GT. <final-value> GOTO 199 ... ... loop statement ... <index-variable> = <initial-value> + <increment> GOTO 100 * .... bottom of indexed loop .... 199 CONTINUE

?

Indexed Looping

?

DO statements (Indexed Looping)

Fortran 77語法: DO <label> <index-var> = <initial-val>,<final-val>[,<increment>] ... ... loop statement ... <label> CONTINUE 1. 第一次執行DO指令,<index-var> = <initial-val>

2. 每執行一次迴圈loop statement,<index-var>就會加上<increment> 但迴圈中不可透過其他程式碼改變 <index-var> 數值,編譯時將發生錯誤 DO 100 count = 1,10 ! 行號 100 表示迴圈程式碼結束位置 i=i+1 ! 改變計數器的值,編譯時將產生錯誤訊息 100 CONTINUE

3. 當 <index-var> ≦ <final-val>,繼續重複迴圈 , 迴圈結束後,<index-var> 一定大於 <final-val> 4. <initial-val>,<final-val>,<increment> 可以使用常數或變數 但需注意的是,變數僅在進入迴圈時被讀取一次,迴圈中改變不影響迴圈 執行狀況 program test integer start , end , inc , i start = 1 end = 10 inc = 1 do i = start, end, inc ! 用enddo做迴圈程式碼結束位置,F90標準,77多支援 start = 3 end = end - 1 inc = -2 print *, i , end ! 可觀察到變數內容的改變不影響 i 從 1 累加到 10 enddo print *, i end

5. <increment> 可以是負數,EX:DO i = 10, 1, -1
6. <increment> 若未提供,預設為 1 EX: 如要計算 2+4+6+8+10+12 ,標準的: ans = 0 ! 給定初值,變數宣告後初值不一定會是 0 DO 100 count = 2,12,2 ! 行號 100 表示迴圈程式碼結束位置 100 ans = ans + count CONTINUE指令沒有實際的用途,利用其做為程式碼的包裝,方便閱讀: ans = 0 ! 給定初值,變數宣告後初值不一定會是 0 DO 100 count = 2,12,2 ans = ans + count 100 CONTINUE ! 迴圈結束後, count = 14

Fortran 90語法:(不需label,使用 enddo 做為結束,多數F77已支援) do <index-var> = <initial-val>,<final-val>[,<increment>] ... ... loop statement ... end do 以上例而言 ans = 0 ! 給定初值,變數宣告後初值不一定會是 0 do count = 2,12,2 ans = ans + count end do ! 迴圈結束後, count = 14 Nested Loops: A loop body may itself contain a loop, and such nesting may be arbitrarily deep. do i = 1, 5 do j = 1, 3 print *, a(i,j) ! 共執行 15 次 print 指令 (5*3) end do end do

?

DO WHILE

do while (logical expression) ! 邏輯運算成立時,執行迴圈內容 ... ... end do DO 迴圈用在可事先知道或控制迴圈執行次數,DO WHILE 迴圈則是不 能預知執行次數時,比如猜數字程式。

?

CYCLE, EXIT

CYCLE、 EXIT 為 Fortran 90新增,但多數 77 的編譯器可用
CYCLE 指令可以略過程式區塊中,CYCLE 指令後面的所有所有程式碼, 直接跳下一次迴圈執行。 EX:對某些較小的資料量採取忽略的動作 do while (.true.) print *, 'Speed = ? (must > 99)' read *, speed if (speed .LT. 100) cycle ! 當speed小於100時,重新開始迴圈 ... end do EXIT 可以直接結束迴圈執行。 EX:做數字總和,有一千筆資料,但若資料為0表示資料已結束,可利用 EXIT 提早結束 迴圈。 do i = 1, 1000 sum = sum + a(i) if (a(i) .EQ. 0) exit ! 當條件成立,提前結束陣列 enddo

?

迴圈命名

迴圈經過命名後,配合end do、cycle、exit的使用,可加強程式可讀性以減少出錯, 並能使結構更具彈性。 命名方法:<cycle_name> : do ... 配合使用:在 end do、cycle、exit 後面加上 <cycle_name> EX: outer: do i = 1, 10 ! 將第一層迴圈命名為 outer inner: do j = 1, 10 ! 將第二層迴圈命名為 inner ... if (i = 3) exit outer ! 當i=3,直接跳離外部迴圈,進行 i=4 迴圈 if (j = 5) cycle inner ! 當j=5,忽略內部迴圈剩下的程式區塊 ... enddo inner enddo outer

陣列
?

一維陣列

宣告方式:<data type> <array name>(<size>) data type可用integer、real、complex、logical也可用自訂型態type 產生 size 組記憶體位置,size 必頇是常數,EX: integer parameter :: count = 10 real a(10), b(count) ! a, b均為包含10個實數的陣列 各種宣告方式: integer a(10) ! 最簡單的方法 integer, dimension(10) :: a ! F90 另一種寫法 INTEGER a ! F77 的作法,先宣告型態,配合下行 DIMENSION a(10) ! 再宣告 a 的容量大小 叫用方法:<array name>(<sequence number>) integer a(10) read *, a(2) ! 從鍵盤輸入數值,置入 a 陣列中第二組記憶體位置 print *, a(2) ! 將 a 陣列中第二組記憶體位置內容印出

?

宣告指定索引值

宣告方式:<data type> <array name>(<low value>:<high value>) integer a(0:10) real b(-100:100) 基本的陣列宣告,如 real a(10) 則 a(n) 代表陣列 a 中第 n 組記憶體位置內容,但經常為了可讀性問題,如數 列 a0,a1,a2,a3,...,a9 ,共十個元素,若宣告為 a(10),則 a(1) = a0 a(2) = a1 在使用上會造成混淆,所以在宣告陣列時可以利用 a(0:10) ,則 a(0) = a0 a(1) = a1 不會造成混淆,此時,a(0)代表陣列 a 中第 1 組記憶體位置內容,a(n)代表 陣列 a 中第 n+1 組記憶體位置內容。 即,宣告<data type> a(i:j),則 a(i+n) 代表第 n+1 個記憶體位置內容。

?

二維陣列
宣告方式:<data type> <array name>(<size, size>) integer a(3,4) real b(0:5,10) 舉例:使用 C(10,4) 記錄班級十位同學,四個科目分數如下表:
座號 1 2 3 ... 國文 80 90 75 ... 英文 85 85 80 數學 75 80 90 歷史 80 90 85

資料可對應如下:
座號 1 2 3 ... 國文 C(1,1) C(2,1) C(3,1) ... 英文 C(1,2) C(2,2) C(3,2) 數學 C(1,3) C(2,3) C(3,3) 歷史 C(1,4) C(2,4) C(3,4)

所以座號 2 同學的數學分數,就是 C(2,3)

各種宣告方式: integer a(10,10) ! 最簡單的方法 integer, dimension(10,10) :: a ! F90 另一種寫法 INTEGER a ! F77 的作法,先宣告型態,配合下行 DIMENSION a(10,10) ! 再宣告 a 的容量大小
?

多維陣列
宣告方式:<data type> <array name>(<size, size, ... , size>),最多到七 維陣列

integer a(3,4,5) read *, a(2,2,3) print *, a(2,2,3)

?

記憶體配置
A(1) B(0) C(1,1) C(2,1) C(3,1) A(2) B(1) A(3) B(2) A(4) B(3) C(1,3) C(2,3) C(3,3) A(5) B(4) C(1,4) C(2,4) C(3,4)

DIMENSION A(5), B(0:4), C(3,4), E(12)

A:

B:
C:

C(1,2) C(2,2) C(3,2)

↓ equivalence C,E
C: E:
C(1,1) C(2,1) C(3,1) C(1,2) C(2,2) C(3,2) C(1,3) C(2,3) C(3,3) C(1,4) C(2,4) C(3,4) E(1) E(2) E(3) E(4) E(5) E(6) E(7) E(8) E(9) E(10) E(11) E(12)

Columnwise storage of data: addr(a(i,j)) = addr(a(1,1))+(j-i)*lda +(i-1) lda is the Leading Dimension of A 效率注意,一起使用的資料,放在同一Column: 資料不連續,效率差 do i = 1, 5 sum = sum + a(1,i) enddo 資料連續,效率好 do i = 1, 5 sum = sum + a(i,1) enddo

另外,多維陣列在處理記憶體位置較耗時,使用時頇注意。
?

大小限制
以 Compaq Visual Fortran 6.5 為例,整個程式使用記憶體大小以 256MB 為上限。 參考錯誤訊息如下: ------------------------------------------------------------Linker Tools Warning LNK4084 total image size size exceeds max (256MB); image may not run The application exceeds the limit of 256 megabytes. -------------------------------------------------------------

?

設定初值.DATA.隱藏式迴圈

和一般變數相同,同樣可以利用DATA來給定初值 integer A(5) data A/1,2,3,4,5/ ! A(1)=1,A(2)=2,A(3)=3,A(4)=4,A(5)=5 data A/5*3/ ! /5*3/表示有5個3,等於/3,3,3,3,3/ ! A(1)=3,A(2)=3,A(3)=3,A(4)=3,A(5)=3 data (A(i),i=2,4) /2,3,4/ ! 使用「隱藏式迴圈」,只設定A(i), i=2,3,4 ! A(2)=2,A(3)=3,A(4)=4, A(1)及A(5)未設定 integer B(2,3) data ( (B(i,j),i=1,2) , j=1,3 ) /1,2,3,4,5,6/ ! 巢狀隱藏式迴圈,B(1,1)=1, B(2,1)=2, B(1,2)=3, B(2,2)=4, B(1,3)=5 ,B(2,3)=6 Fortran 90新增:(省去DATA) integer :: a(5) = (/1,2,3,4,5/) ! 直接宣告並給初值,但必頇5個元素都給 ! A(1)=1,A(2)=2,A(3)=3,A(4)=4,A(5)=5 integer :: a(5) = (/1,(2,i=2,4),5/) ! 結合隱藏式迴圈 ! A(1)=1,A(2)=2,A(3)=2,A(4)=2,A(5)=5 integer :: a(5) = (/(i,i=1,5)/) ! A(i)=i, i=1~5

?

ALLOCATABLE - Fortran 90新增

一般在宣告陣列時必頇指定大小,但有些問題在執行階段才知道需 要多大的陣列,這時經常的解決辦法就是宣告一個足夠大的陣列, 並告知使用者操作限制,如: integer student(100), stu_count print *,"輸入學生人數(MAX:100)" read *, stu_count do i = 1, stu_count print *, "請輸入第",i,"位同學成績" read *, student(i) end do ...

Fortran 90則可以透過ALLOCATABLE來解決這個問題: integer, allocatable :: student(:) ! 宣告一個可變大小的一維陣列 integer :: stu_count print *,"輸入學生人數:" read *, stu_count allocate( student(stu_count) ) ! 配置stu_count個記憶體空間 do i = 1, stu_count print *, "請輸入第",i,"位同學成績" read *, student(i) end do ...

宣告注意: 這裡需要 allocatable 和 allocate 兩個指令的配合,allocatable配合陣列 宣告時使用,但陣列大小以「:」代替即可;當知道所需陣列大小 時,再以 allocate 配置記憶體空間大小。 ? 配置是否成功: 由於記憶體是有限的,不一定每次都會配置成功,如何得知是否配 置成功?可寫成 allocate( student(stu_count), stat=error ) ,error是宣告 好的整數變數,若成功,error傳為 0 ,其他數值表示失敗。 ? 解除配置空間: 當該空間使用完畢,也可以透過 deallocate 指令來釋放配置空間: 如:deallocate( student ) 完整的語法如下: DEALLOCATE ( object [, object] ...[, STAT=sv] ) object: Is a structure component or the name of a variable, and must be a pointer or allocatable array. sv: Is a scalar integer variable in which the status of the deallocation is stored.
?

?

多維陣列:
integer, allocatable :: stu_2(:,:) ! 兩個冒號代表二維陣列 integer, allocatable :: stu_3(:,:,:) ! 三個冒號代表三維陣列 allocate( stu_2(3,3) ) allocate( stu_2(4,4,4) )

?

指定索引座標範圍:
integer, allocatable :: stu_1(:) integer, allocatable :: stu_2(:,:) allocate( stu_1(-3:3) ) allocate( stu_2(-3:3,0:5) ) ! 兩個冒號代表二維陣列

?

相關函數:
allocated 可傳回陣列是否已經配置記憶體

?

ALLOCATED

檢查一可變大小的矩陣是否已經配置記憶體,函數會傳回一個邏輯值。 如: if ( .not. allocated(a) ) then allocate( a(5) ) end if 上例中,檢查陣列 a 是否已經配置,若無,則配置 5 個記憶體空間。 相關指令請參考:allocatable

函式
函式是Subroutine(副程式)與Function(自訂函數)的統稱。

迴圈可以讓程式在相同的地方重複執行某一段程式碼,函式 則可以在不同的地方被重複使用,二者的應用範圍不同。
撰寫程式時,當某一段具備特定功能的程式碼被重複撰寫時, 可以將之包裝成函式,在使用時叫用該段函式(比如使用 CALL指令呼叫副程式),如此可使得程式撰寫更有效率,可 讀性也增加許多。

?

Subroutine(副程式)

舉例如下: ! 使用者輸入兩個數字,傳入swap函式做交換後輸出 ! 本例可用DO迴圈,但利用函式,在程式其他部分也可以呼叫函式功能 program Swap_2_Real do while (.true) read *, value1, value2 ! 使用這從鍵盤輸入兩數字 if (value1 .eq. value2) stop ! 若輸入兩數字相同,則停止程式 call swap(value1, value2) ! 呼叫 swap函式,做兩數交換 print *, value1, value2 ! 將交換之兩數印出 end do stop end

! 交換兩數的函式 - swap subroutine swap(a, b) real a, b real temp temp = a ! 將 a 值先做保留 a=b ! 將 b 的值置入 a 記憶體位置中 b = temp ! 將剛剛保留下的 a 值置入 b 記憶體位置中 return ! 返回呼叫程式 end 語法: Calling programs (main program, subroutines) CALL <subr. name>[([<actual argument list>])] -------------------------------------------------Called programs (subroutines, intrinsic functions) SUBROUTINE <subr. name>[([<dummy argument list>])] END [SUBROUTINE [<subr. name>]] (Fortran 77只用END) -------------------------------------------------Note:Arguments are passed by reference: that is, their addresses are passed.

注意事項: ? 副程式的命名應有意義並且不隨意變更,因為副程式可能提供多個程式呼叫使用, 甚至由團隊中不同人員叫用;修正時,需修改原程式叫用部分並更新相關文件。 ? 原始檔中,未規定主程式program與副程式subroutine先後順序;但編譯後執行,主 程式會被自動執行,副程式則是被動需被叫用才執行。 ? 要返回主程式使用return指令,return可放在副程式中任意位置;使用stop會使主程 式也停止。 ? 呼叫端可以是主程式,也可以是副程式。 ? Fortran 90 進一步支援副程式自己呼叫自己,稱為遞迴。 ?副程式除傳遞進入的變數外,可以獨立宣告屬於自己的變數,既使變數名稱與主 程式相同亦可。 ? 副程式傳遞變數採用傳址呼叫(call by address / call by reference),即傳遞記憶體 位置,前例中,value1 和 a 指著相同的記憶體位置。 ? 註:另一種稱「傳值呼叫」,在副程式中傳遞變數也會有獨立的記憶體位置,改 變內容不影響呼叫端的變數內容。

?

Function(自訂函數)

舉例如下: ! 使用者輸入數字 x,計算 x2 - 2x + 1 值 program func_test real x, y do while (.ture.) ! 設定為無窮迴圈 read *, x ! 使用者輸入 x y = f(x) ! 呼叫 f 函數計算 x2 - 2x + 1 print *, y ! y = f(x)、print *, y 兩行可合併為 print *,f(x) end do end -----------------------------------------real function f(x) ! 宣告函數 f 傳回的型態為real real x f = x**2 – 2*x + 1 return end

語法: Calling programs (main program, subroutines) <function name>[([<actual argument list>])] -------------------------------------------------Called programs (functions) [<type>] FUNCTION <func. name>[([<dummy argument list>])] END [FUNCTION [<func. name>]] (Fortran 77只用END) -------------------------------------------------Passed by address: if an actual argument is a variable name, array name, array element or a substring Passed by value: if the actual argument is any other expression (including a constant)

注意事項: ? 函數型態的宣告可以寫在函數的最開頭,如 real function f(x) 或是放在變數宣告區塊,如 function f(x) real f, x ? 呼叫端可將函數名稱做 EXTERNAL 宣告,表示該名稱不是變數,而 是函數名稱。當函數名稱做為變數傳遞時,不可省略。 ? 叫用時不需使用 CALL 指令,直接寫出[名稱]即可,如 print *, f(x) a = f(1.0) + f(2.0) b = f( f(1.0) ) ? 傳遞變數若非運算式或常數,則採傳址呼叫,但在function中,一般 不會去改變該變數的內容,這是一個不成文的習慣。若要改變傳入變 數的內容,請改用subroutine。

?

Statement Function

若函數只包含一個運算式,又只在同一個主程式或函式中被使用,可以 使用 statement function 的寫法,在 Function 中的例子變成: program func_test real x, f f(x) = x**2 – 2*x + 1 ! 直接定義函數 do while (.ture) read *, x ! 使用者輸入 x print *, f(x) ! 呼叫 f 函數計算 x2 - 2x + 1,並輸出 end do end

語法: [<type>] <function name> <function name>([<dummy argument list>])=<expression> 注意事項: ? 上例中 real x, f f(x) = x**2 – 2*x + 1 叫用時不一定只能使用 f(x),可以是其他變數、常數或是運算式, 如 print *, f(a) , f(1.0) , f(a+2.0) , f(f(a))

?

COMMON(全域變數)

不同的函式間,除了透過參數的傳遞來共享記憶體外,還可以經由「全域變數」 讓不同的函式中變數,使用相同的記憶體位置。請先看一個簡單的範例如下: program common_ex integer a, b common a, b a = 99 b = 100 call ShowCommon() end subroutine ShowCommon() integer num1, num2 common num1, num2 print *, num1, num2 return end

執行結果輸出所得為「99,100」 其變數參照方式是以「位置對應」,上例中,主程式端宣告為全域變數第一 個為 a ,第二個是 b ;而副程式 ShowCommon 中第一個是 num1 ,第二個 是 num2 ;所以 num1 會指到同為第一個變數 a 的記憶體位置,num2 則會指 到同為第二個變數 b 的記憶體位置。 ? 利用位置對應的小技巧:(也讓你更清楚什麼是位置對應的關係) 主程式:common a,b integer a,b 副程式:common num integer num(2) ! 則num(1)對應到主程式的 a ,num(2)對應到主程式的 b

? 分組宣告: 由於是按位置對應,在全域變數多時,宣告將成為困擾,假設共有十個全域 變數,但副程式只需要最後兩個,仍要全部宣告: 主程式program_main:common a,b,c,d,e,f,g,h,i,j 副程式subroutine_1:common p,q,r,s,t ! 只用前5個變數,故宣告5個 即可 副程式subroutine_2:common p,q,r,s,t,u,v,w,x,y ! 只用到最後兩個,但需全部 宣告 既使副程式subroutine_2只用到主程式中i,j兩變數,但由於全域變數是以宣告 順序來對應,所以在副程式中,仍頇宣告十個全域變數,如此才能對應到我 們要的第八和第九個變數i.j。 要解決這個問題,讓程式碼更簡明,可以用以下的方法將全域變數「分組」 主程式: common /group1/ a, b common /group2/ c, d 副程式-1: common /group1/ num1. num2 ! 分別對應到主程式的 a, b 副程式-2: common /group2/ num1. num2 ! 分別對應到主程式的 c, d

注意事項: ? 宣告成 COMMON 的變數,不能使用 DATA 來給定初值。 ? 全域變數和傳遞參數一樣都可以讓不同的程序使用相同的變數內容,使用時機 有何不同呢?一般來說,若有許多不同的程序都會使用到相同的記憶體區塊, 便可以考慮宣告成全域變數。 ? 全域變數不能宣告為常數。 ? 全域變數宣告型態需一致,否則將造成讀取資料的錯誤: (全域變數只是使用相同的記憶體區塊「起始位置」,至於區塊大小以及解碼 方式,按宣告型態而定) 主程式:common a real a a = 1.0 副程式:common num integer num ! 則num對應到主程式的 a ! 但 a 為浮點數,num 為整數 print *, num ! 輸出為 1065353216 上例來說,主程式 a = 1.0 ,浮點數表示法將記錄為 00111111100000000000000000000000,但 num 為整數,只讀取 2 位元組,且用 一般二進位補數表示法解讀,所得為 1065353216。 若num宣告為短整數(2位元組),又會有不同的結果。

?

BLOCK DATA

上前一段 DATA 的範例中,若要使用 DATA 給定初值,需使用 BLOCK DATA 敘述。我們稍微修改範例如下: program common_ex integer a, b, c, d common a, b ! 放在不具名的全域變數空間中 common /group1/ c, d ! 放在分組名稱為 group1 的全域變數空間中 print *, a, b, c, d end

block data implicit none integer a, b common a, b data a, b /99, 100/ integer c, d common /group1/ c, d data c, d /101, 102/ end data block 執行結果為:「 99 100 101 102 」 注意事項: ? BLOCK DATA 類似副程式,但是不需要被別人呼叫。 ? 在主程式執行前就會生效,意即主程式執行前,初值已寫入記憶體區塊中。 ? 該段程式碼只放置與宣告有關的敘述,不可有設定初值以外的指令出現。 ? 全域變數不能宣告為常數,故不能出現 PARAMETER 。

?

傳址呼叫問題與技巧

? 字串傳遞問題: 副程式中需要宣告不定長度的字串(即字串長度由父程序中決定) function test(a,b,c) character*(*) a ! F77語法 character(*) b ! F90語法 character(len=*) c ! F90語法 ... end function

檔案處理
在檔案處理中,如果處理的檔案都是循序檔(sequential files), 即檔案中每一記錄 都是循序寫入的, 而且也必頇循序讀出。 表示要在循序檔中讀出一特定記錄, 之前所有記錄必頇先讀 出。另一種檔案稱為直接接達檔(direct-access files),檔案中每 一記錄可以直接讀寫, 通常是經由記錄號碼。直接接達檔中 所有記錄, 其長度必頇相同, 而且不能更動。循序檔中的記 錄長度可以變動。 檔案也可分成有格式和無格式兩種。目前 提及的檔案都是有格式的。有格式的檔案中記錄所含資訊是 用外顯字元的形式表示,而無格式的檔案中記錄則是用 二進 形式表示。因此無格式的檔案中記錄的確實形式, 隨機器而 有所不同。

?

OPEN, CLOSE, 和 INQUIRE 敘述
?

開檔 在使用檔案輸入或輸出之前,檔案必頇先標明所用的單位規定式號碼。 OPEN 敘述的一般形式為 OPEN ( open-list ) 其中 open-list必頇包括

單位規定式 單位規定式的形式為, UNIT = integer-exp 或 integer-exp 其 中 integer-exp 的數值是零或正整數, 指定檔案的單位號碼。 READ 或 WRITE 敘述使用此單位號碼讀寫其連接的檔案。 使用第二種形式時, integer-exp必頇是open-list的第一項。

FILE = 子句 FILE = 子句的形式為, FILE = char-exp 其中 char-exp (略去末尾的空白)是單位號 碼所連接的檔案名稱。 STATUS = 子句 STATUS = 子句的形式為, STATUS = char-exp 其中 char-exp (略去末尾的空白) 之 值是下列之一: OLD 舊檔, 必頇用 FILE = 子句規定檔名。 NEW 新檔, 必頇用 FILE = 子句規定檔名。 SCRATCH 草稿檔, 必頇不用檔名。 UNKNOWN 未知檔, 以上皆非。 若省略 STATUS = 子句, 則預設為未知檔。 IOSTAT = 子句 FILE = 子句的形式為, IOSTAT = int-var 其中 int-var 之值為零或正整數。 開檔順 利, 則為零。否則為正整數, 代表系統手冊中的錯誤信文之號碼。 ERR = 子句 ERR = 子句的形式為, ERR = n 其中 n 規定若在開檔發生錯誤時,所要執行檔案 的號碼。

ACCESS = 子句 ACCESS = 子句的形式為, ACCESS = char-exp 其中 char-exp (略去末尾的空 白) 之值是下列之一: SEQUENTIAL 規定檔案是循序 DIRECT 規定檔案是直接 若省略此子句, 則預設為循序檔。 FORM = 子句 FORM = 子句的形式為, FORM = char-exp 其中 char-exp (略去末尾的空白) 之值是下列之一: FORMATTED 規定檔案是有格式的 UNFORMATTED 規定檔 案是無格式的 若省略此子句, 則循序檔預設為有格式的, 而直接檔預設為無 格式的。 RECL = 子句 RECL = 子句的形式為, RECL = int-exp 其中 int-exp 之值為正。 此子句只在 直接接達檔使用,規定其記錄長度。 在有格式檔, 指的是 該檔每一記錄的字 元數,在無格式檔, 則視處理器(processor)而定。 BLANK = 子句 BLANK = 子句的形式為, BLANK = char-exp 其中 char-exp (略去末尾的空白) 之值是下列之一: ZERO 規定數值欄中的空白是當做 0。 NULL 規定略過數值 欄中的空白。 若數值欄中全是空白, 則不論 ZERO 或 NULL, 都當做 0。

?

關檔

CLOSE 敘述用以切斷檔案和單位號碼的連接。 CLOSE 敘述的一般形式為 CLOSE ( close-list ) 其中 close-list 必頇包括單位規定式 也可包括選自下列的其他規定式: IOSTAT =子句,指示檔案是否順利關閉。 ERR =子句,規定若在關檔發生錯誤時,所要執行檔案的號碼。 STATUS =子句,規定檔案要保留或刪除。 STATUS = 子句的形式為, STATUS = char-exp 其中 char-exp (略去末尾的空白) 之 值是下列之一: KEEP 規定關檔後保留該檔。 DELETE 規定關檔後刪除該檔。 SCRATCH 檔不可用 KEEP。 若省略 STATUS = 子句, 則刪除草稿檔, 保留其 他類型的檔案。 檔案用CLOSE 敘述關閉後, 可以再用OPEN敘述打開,可用 同一單位號碼, 也可用不同的 號碼。 所有未關閉的檔案,在程式終止執行時 (由於發生錯誤而導致的不正常終止除外),都自動關閉。


相关文章:
完整的Pascal讲义(word)
完整的Pascal讲义(word)_IT认证_资格考试/认证_教育专区。第一课 初识 Pascal ...在结构化这一点 上,比其它(如 BASIC,FORTRAN77)更好一些。 ⒉有丰富的数据...
强化班讲义
FORTRAN概述 13页 免费 学英语必看英语语法手册(全... 98页 免费 D小学六年级...数学讲义数学讲义隐藏>> 强化班讲义(概率统计) 强化班讲义(概率统计)第一讲 随...
Fortran讲义 补充版
Fortran讲义 补充版_理学_高等教育_教育专区。计算物理很好的计算物理主要内容计算机、数值方法和物理的结合。 Fortran 语言、计算方法、绘图 物理问题的计算机实现:分析...
fortran语法手册
9 FORTRAN77 函数与子程序 9.1 FORTRAN77 语句函数 当函数十分简单,用一条语句足以定义时(允许使用继续行)才用; 应该放在所有可执行语句之前和有关类型说明语句...
fortran初步学习资料
fortran初步学习资料_建筑/土木_工程科技_专业资料。fortran入门学习资料第一章: Fortran 语言程序设计初步 Fortran 语言的发展概况本节介绍 Fortran 的起源与发展历史...
Fortran语言基础
Fortran语言基础_IT/计算机_专业资料。山东建筑大学 数值分析程序设计 Part I Fortran 语言 语言基础 COMPAQ VISUAL FORTRAN 6.5 0 编译器的使用 0.1 编译器简介...
FORTRAN语言自学基础
FORTRAN语言自学基础_IT/计算机_专业资料。《FORTRAN 语言》自学提纲 第一章 1 FORTRAN 基础 1. 一个 FORTRAN 程序由一个主程序或一个主程序与若干个子程序组成。...
fortran语言语法
fortran语言语法_IT/计算机_专业资料。fortran的基本语法FORTRAN 是世界上最早出现的高级编程语言,是工程界最常用的编程语言, 它在科学计算中(如航空航天、地质勘探、...
FORTRAN学习中的一些小心得
FORTRAN学习中的一些小心得_计算机软件及应用_IT/计算机_专业资料。简要介绍了FORTRAN学习中的一些小心得和技巧,比较简单 FORTRAN 心得第一部分:一些小心得 Fortran ...
FORTRAN经典入门程序20例
FORTRAN经典入门程序20例_计算机软件及应用_IT/计算机_专业资料。适用于FORTRAN初学者的练习例子 对于FORTRAN的初学者。这些例子可作为小练习。 1.例题:计算工资问题...
更多相关标签:
fortran | fortran编译器 | intel visual fortran | fortran下载 | intel fortran | fortran语言 | fortran教程 | visual fortran |