fortran基礎知識
語句結構
- fortran語句分爲兩種: 可執行語句、不可執行語句
- fortran語句可以書寫行的任意位置,語句間行間的銜接用
&
符號,類似c/c++語言中的\
- 語句標號是fortran語句的名字,可以使用1~99999之間的任何一個數字,使用標號可以在程序的其他部分引用這條語句。
- 感嘆號是註釋
- 程序分爲3個部分:
- 聲明部分:定義程序名和程序引用的數據以及變量的類型
program語句,對fortran編譯器指定程序的名字,必須是程序的第一個語句行 - 執行部分:描述語句完成的操作
- 終止部分,由一條或終止程序執行的語句組成
終止部分由STOP和END PROGRAM語句組成,STOP語句告訴計算機停止運行,END PROGRAM語句告訴編譯器程序中不再有語句需要編譯。
- 聲明部分:定義程序名和程序引用的數據以及變量的類型
程序書寫格式
- 保留字大寫,程序的變量用小寫字母表示。大寫保留字和常量,變量名、過程名等則小寫。
編譯、鏈接、執行
- 兩種方式
- 批處理
- 交互處理
fortran數據類型
- 三個對數字有效:INTEGER,REAL,COMPLEX
- 一個邏輯:LOGICAL
- 一個字符串:CHARACTER
- fortran允許定義派生數據類型
實型變量由2部分組成:尾數和指數,分配給存放尾數的位數決定常量的精度
- 字符常量與變量
字符類型由字母字符串組成,一個字符常數是單引號或雙引號括住的字符串。兩個連續的單引號包含着重符。
- 定義變量類型的方式:
- 默認式
任何以字母I,J,K,L,M或N開頭的變量名假定爲INETEGER,其他字母開頭的變量名假定爲REAL。 - 顯示定義:
INTEHER::var1,var2....
REAL :: var1,var2
- 默認式
- 常數命名
用PARAMETER屬性來創建,格式:type,PARAMETER::name=value [,name2=value2,...]
type是常數的類型,name是賦給常數value的名字
fortran算數運算符
- / **(指數運算)
整型運算是沒有小數點,直接截斷
- 在混合模式下,在進行實數與整數操作的情況下,計算機將整數轉換爲實數,然後進行實數運算。
- 類型轉化函數
INT(X) NINT(X) CEILING(X) FLOOR(X) REAL(I)
輸入和輸出語句
輸入語句格式:
READ (*,*) input_list
input_list是讀入的值放置在裏面的變量列表。
圓括號(.)的第一數據域指明從哪個輸入/輸出單元 ,星號意味着從標準輸入讀。圓括號的第二個數據域指明讀入數據的格式,星號意味着表控輸入,又稱自由格式輸入。
表控輸入意味着變量列表中的變量類型決定輸入數據所需要的格式
對於表控輸入,如果含有空格,輸入字符串必須用單或雙引號括住
程序的每條READ語句從輸入數據的一個新行開始讀取。表控輸出格式:
WRITE (*.*) Output_list
3種初始化變量
- 賦值語句
- READ語句
- 類型聲明語句中的初始化
type:: var1=value,[value=value,...]
IMPLICIT NONE語句
- IMPLICIT NONE語句使Fortran中默認提供輸入值的功能喪失,當程序含有IMPLICIT NONE語句,沒有出現在顯示類型聲明語句中的變量被認爲是錯誤的。IMPLICIT NONE語句出現在PROGRAM語句之後和類型語句之前。
IMPLICIT NONE語句強制程序中所有的變量要顯示聲明類型。
STOP語句
STOP語句停止fortran程序的執行,程序可以有許多條STOP語句.
程序設計與分支結構
邏輯常數和變量
下列數值中的一個:.TRUE
,.FALSE
邏輯變量利用LOGICAL語句來聲明:LOGICAL:: var1[,var2,var3...]
關係運算符
新形式 | 舊形式 | 意義 |
---|---|---|
== | .EQ. | 等於 |
/= | .NE. | 不等於 |
> | .GT. | 大於 |
= |
.GE. | 大於或等於 |
< | .LT. | 小於 |
<= | .LE. | 小於或等於 |
輸入輸出語句中的邏輯值
邏輯變量出現在以READ開頭的語句中,相應的輸入值必須以T或F開頭的一個或一組字符。如果輸入的字符是T,那麼邏輯變量就是.TRUE.
如果輸入的第一個字符是F,那麼邏輯變量就是.FALASE.
控制結構:分支
- IF語句格式:
IF (logical_expr) THEN
statement1
statement2
…
END IF
IF(...) then
是一個fortran語句,必須一起寫在同一行上,並且要執行的語句必須佔用IF(…)then語句下面單獨的一行。緊隨其後的END IF語句必須另起一行,在包含end if語句的行上不能有行號。
ELSE和ELSE IF子句
語句1 語句2 ... ELSE IF(邏輯表達式2) THEN 語句1 語句2 ... ELSE 語句1 語句2 ... END IF
命名的IF結構塊
帶有名稱的結構的一般形式爲
[名稱: ] IF(邏輯表達式_1) THEN
語句1
語句2
…
ELSE IF(邏輯表達式_2) THEN [名稱]
語句1
語句2
…
ELSE [名詞]
語句1
語句2
…
END IF [名稱]邏輯IF語句
IF(邏輯表達式) 語句
select case結構
- 一般形式
[name:] SELECT CASE (case_expr)
CASE (情況選擇子_1) [name]
語句1
語句2
...
CASE (情況選擇子_2) [name]
語句1
語句2
...
CASE DEFAULT [name]
語句1
語句2
...
END SELECT [name]
如果給SELECT CASE語句指定了名字,那麼必須在相關的END SELECT上出現相同的名字。
循環和字符操作
循環有2種結構:當循環和迭代循環(計數循環)
1. 當循環
DO
...
IF(邏輯表達式) EXIT
...
END DO
在DO和END DO之間不間斷重複運行,直到邏輯表達式爲真,執行了EXIT語句。當EXIT語句執行後,控制語句轉到END DO之後的第一條語句處。
DO WHILE循環
“`
DO WHILE(邏輯表達式)
…
…
…
END DO計數循環
“`
DO index=istart,iend,incr
語句1
語句2
END DO
incr如果缺少,默認是1
3個循環參數istart,iend,incr可以是常量、變量或者表達式。如果是變量或者表達式,其值是在循環開始前進行計算,產生的數值用於控制循環。
如果index*incr《=iend*incr,程序執行循環體內的數據。
只要index*incr <=iend*incr,就反覆執行。CYCLE和EXIT語句
如果CYCLE語句在循環體內執行,當前循環的執行將被終止,控制器將返回到循環的頂部。(相當於C中的continue語句)
如果在循環中執行EXIT語句,循環的執行將終止,控制器將轉到循環後面的第一條可執行語句處。命名循環
帶有名稱的當循環
[名稱:]DO
語句
語句
語句
IF(邏輯表達式) CYCLE [名稱]
…
IF(邏輯表達式) EXIT [名稱]
END DO帶有名稱的計數循環
[名稱:] DO index=istart,iend,incr
語句
語句
IF(邏輯表達式) CYCLE [名稱]
…
END DO[名稱]
字符賦值和字符操作
可以通過字符表達式操作字符數據,字符表達式可以由有效的字符常量、字符變量、字符操作符和字符函數組成。
字符操作符是一種作用於字符數據併產生字符結果的操作符。
字符操作符有2種基本類型:子字符串抽取和連接。
- 字符賦值
如果字符表達式的長度短語字符變量的長度,多餘部分用空格補充
如果字符表達式的長度長於字符變量的長度,則截斷。
子串抽取
一個子串表示爲,在變量名後面的括號中放置兩個由逗號隔開的表示開始和結束的字符編號的整數數值。如果字符結束編號小於開始編號,則返回空串。連接(//)操作符
可以將兩個或多個字符串或子串合併成一個大的字符串,這個操作稱爲連接。fortran中連接操作符是雙斜線,斜線間無空格。字符數據的關係操作符
ASCII字符比較,字符不能與整型比較,只能字符之間比較。內置字符函數
基本的I/O概念
格式和格式化語句
- 格式可以指定程序輸出打印變量的確切方式。指定變量在紙上的水平或垂直位置,也可指定打印的有效位數。
- format語句
WRITE (*,100) i, result
100 FORMAT (' The result for iteration',I3,'is',F7.3)
- 字符變量語句
CHARACTER(len=20) :: string
string='(1X,I6,F10.2)'
- 字符常量語句
WRITE(*,'string='(1X,I6,F10.2))
輸出設備
輸出緩衝區的第一個字符稱爲控制字符,指定了行的垂直間距。
對於表控輸出[WRITE(,)],空格字符被自動地插入到每個輸出緩衝區的開頭。
格式描述符
- 四個類別:
1.描述文本行垂直位置的格式描述符
2.描述行中數據水平位置的格式描述符
3.描述特定數值的輸出格式的格式描述符
4.控制格式中一部分的重複的格式描述符 格式描述符符號
符號 含義 c 列號 d 實數輸入或輸出小數位右邊的位數 m 要顯示的最小位數 n 要跳過的空格數 r 重複計數——一個描述符或一組描述符的使用次數 w 域寬——輸入或輸出使用的字符數 整數輸出——I描述符
格式如下:rIw或rIw.m
- 實數輸出——F描述符
格式如下:rFw.d
- 實數輸出——E描述符
以指數表示法打印輸出
格式:rEw.d
E格式描述符域寬度必須滿足w>=d+7 - 真正的科學記數——ES描述符
ES格式描述符具有的格式:rESw.d
ES域必須滿足w>=d+7 - 邏輯輸出——L描述符
格式:rLw
邏輯變量的值只能使用.TRUE或.FALSE
邏輯變量的輸出爲T或F,在輸出域內在右對齊 - 字符輸出——A描述符
格式:rA
或rAw
- 水平定位——X和T描述符
這兩種格式描述符控制數據在輸出緩衝區中的間距以及在最終輸出行上的間距。
可以在緩衝區中插入間距的X描述符,以及可以在緩衝區中跳過特定列的T描述符。
X描述符的格式爲:nX
,n爲要插入的空格數,用於在輸出行上的兩個數值之間添加一個或多個空格
T描述符的格式爲:Tc
,c是要轉到的列號,用來直接跳到輸出緩衝區中一特定的列。 - 格式描述符組的重複執行
格式化READ語句
- 整數輸入——I描述符
讀取整數數據的描述符rIw
- 實數輸入——F描述符
F描述符是用於描述實數數據的輸入格式的格式描述符rFw.d
- 邏輯輸入——L描述符
語法:rLw
- 字符輸入——A描述符
語法rA
或rAw
,rA描述符讀取一個域中的字符數據,域寬度與被讀取的字符變量的長度相同,rAw描述符讀取一個具有固定寬度w的域中的字符數據。 - 水平定位——X和T描述符
X描述符的主要作用是跳過不想讀取的輸入數據的區域。
T描述符也可,用兩種不同的格式讀取相同的數據。 - 垂直定位——斜線(/)描述符
斜線格式描述符可以使格式化READ語句放棄當前輸入緩衝區的內容,而從輸入設備中獲取另一個,然後從新的輸入緩衝區的頭部開始處理,
文件及文件處理初步
OPEN語句
OPEN語句講一個文件與一個給定的I/O單元號關聯
格式:OPEN(open_list)
包含一組子句,分別指定I/O單元代號、文件名和關於如何存取文件的信息。- UNIT=子句指明與文件關聯的I/O單元代號
格式如下:UNIT=int_expr
- FILE=子句指定要打開的文件名
格式如下:FILE=char_expr
- STATUS=子句指定要打開文件的狀態
格式如下:STATUS=char_expr
- ACTION=子句指定一個文件是否以只讀、只寫或讀寫方式打開。
格式如下:ACTION=char——expr
- IOSTAT=子句指定一個整數變量名,打開操作的狀態可以返回到這個變量中。
格式如下:IOSTAT=int_var
- IOMSG=子句指定一個字符變量名,如果發生錯誤,它就包含錯誤信息。(FRTRAN 2003特性)
格式如下:IOMSG=chart_var
- UNIT=子句指明與文件關聯的I/O單元代號
CLOSE語句
close語句關閉一個文件並釋放與之關聯的I/O單元代號
格式如下:CLOSE(close_list)
close_list必須包含一個指定I/O單元代號的子句,還可以指定其他選項。- READ語句中的IOSTAT=和IOMSG=子句
當使用磁盤文件時,可以給READ語句增加IOSTAT=和IOMSG=子句
格式:IOSTAT=int_var
int_var是整型變量,如果READ成功執行,返回0。如果失敗,返回一個相對應的錯誤整數。如果到達輸入數據文件的尾部而使語句執行失敗,就給該變量返回一個負數。 - 文件定位
BACKSPACE語句,每次調用它可以回退一個記錄;BACKSPACE(UNIT=unit)
REWIND語句,可以在文件頭重新開始文件。語句格式:REWIND(UNIT=unit)
- READ語句中的IOSTAT=和IOMSG=子句
數組
- 聲明數組
數組的聲明包含元素類型和個數。
例如:聲明16個元素的實型數組voltage,REAL,DIMENSION(16)::voltage
DIMENSION屬性說明被定義數組的大小。 - 在Fortran語句中使用數組元素
數組元素初始化三種方式: - 賦值語句初始化數組
- 編譯時在類型聲明語句中初始化數組
用數組構建器聲明相應語句中數組的初始值(/..../)
隱式DO循環,常規格式:(arg1,arg2,...,index=istart,iend,incr)
爲指定下標的取值範圍,可以在聲明語句中包含起始下標和結束下標的數據,其間用冒號隔開。
REAL,DIMENSION(lower_bound:upper_bound)::array
大多數fortran編譯器越界檢查可選,打開這個選項,程序運行很慢,可以關閉越界檢查,程序運行會快。
- 在數組聲明中使用有名常數
用簡單修改單個有名常數MAX_SIZE可以輕易改變所有數組的大小。
- 在數組聲明中使用有名常數
- 用READ語句初始化數組
fortran語句中使用整個數組和部分數組
- 操作部分數組
局部數組被稱爲部分數組。部分數組用下標三元組或向量下標代替數組下標來指定
常見形式:subscript_1:subscript_2:stride
subscript_1是包含在部分數組中的第一個下標,subscript_2包含在部分數組中的最後一個下標,stride是遍歷數據集時的下標增量。
輸入和輸出
- 數組元素的輸入和輸出
隱式DO循環
隱式DO循環的WRITE和READ語句
WRITE(unit,format) (arg1,arg2,...,index=istart,iend,incr)
READ(unit,format)(arg1,arg2,...,index=istart,iend,incr)
整個數組和部分數組的輸入和輸出
過程
fortran可以在構建最終的程序前較容易地獨立開發和調試子任務,可以把每個子任務作爲獨立的程序單元來編碼,該獨立程序單元被稱爲外部過程,每個外部過程都可以獨立於程序中的其他子任務來進行編譯、測試和調試。
Fortran有兩種外部過程:子程序和函數子程序。
- 子程序通過在一個單獨的CALL語句中引入子程序名來進行調用,並且可以通過調用參數來返回多個結果,
- 通過在表達式中引入函數名來進行調用,它的結果是單個數值,該值用來爲表達式賦值。
子程序
子程序(subroutine)是一個fortran子過程,通過在CALL語句中使用過程名來調用,並通過參數表來獲取輸入參數,返回計算值,子程序的通用格式如下:
SUBROUTINE subroutine_name (argument_list)
...
(Declaration section)
...
(Execution section)
...
RETURN
END SUBROUTINE [name]
SUBROUTINE語句標誌着子程序的開始,定義子程序名和相關參數表。
子程序命名遵循fortran命名規則:由字母和數字組成,最大31個字符,第一個字符必須爲字母。
子程序必須包含聲明部分和執行部分。當程序調用子程序時,調用程序的執行暫時被掛起,子程序執行部分開始運行。當運行到子程序的RETURN語句或END SUBROUTINE語句時,調用程序又開始運行調用子程序語句下面的代碼。
調用程序使用CALL語句來調用子程序。CALL語句的格式如下:
CALL subroutine_name (argument_list)
1. INTENT屬性
子程序的形參可以與一個INTENT屬性聯合使用。INTENT屬性與類型聲明語句聯合使用,來聲明每個形參的類型。可以寫成下列中的形式:
INTENT(IN) 形參用於向子程序傳遞輸入參數
INTENT(OUT) 形參僅用於將結果返回給調用程序
INTENT(INOUT) 形參用來向子程序輸入數據,也用來向調用程序返回結果
- Fortran中的變量傳遞:地址傳遞方案
Fortran程序和它的子程序之間用地址傳遞方案來進行通信。
當調用子程序時,主程序傳遞一個指針來指向實參表中各個參數的存儲位置。子程序查找調用程序所指向的內存位置,以獲得它需要的形參值。 - 傳遞數組給子程序
子程序中3種可能方式指明形參數組的大小。
第一種方法實在子程序調用時,將數組每一維度的邊界值傳遞給子程序,並且聲明相應的形參數組爲該長度。
第二種方法是把子程序中的所有形參數組聲明爲不定結構的形參數組,以創建一個子程序的顯示接口。
第三種方法是用星號(*)來聲明每一個形參數組的長度,這些數組被看成是不定大小的形參數組。(早期行爲) - 傳遞字符變量給子程序
當一個字符變量被作爲子程序的形參時,用*來聲明字符變量的長度。因爲沒有實際給形參分配內存,所以在編譯時不是必須直到字符參數的長度。 - 子程序中錯誤處理
永遠不要在子程序用使用stop語句
用模塊共享數據
除了參數表之外,Fortran程序、子程序以及函數也可以通過模板來交換數據。
模塊是一個獨立編譯的程序單元,包含了在程序單元間共享的數據的定義和初始值。
如果程序單元中使用了包含模塊名的USE語句,則在那個程序單元中可以使用模塊中定義的數據。使用同一個模板的程序單元可以訪問同樣的數據。模塊是一個程序提供單元共享數據的方式。
模塊以MODULE語句來表示開始,該語句指明瞭模塊的名字。模塊名的最大長度可達31字符。模塊以END MODULE語句結束。
SAVE語句能夠保證在模塊中聲明的數據被保護在不同過程間的引用中,所以共享數據應該始終被聲明在模塊中。
要使用模塊中的數值,程序單元必須使用USE語句聲明模塊名。USE語句格式如下:USE module_name
USE語句必須出現在程序單元中的其他語句之前,除了PROGRAM或SUNROUTINE語句,也除了可以出現在任意位置的註釋語句。用USE語句來訪問模塊中的數據被稱爲USE關聯。
模塊過程
模塊除了可以有數據之外,還可以有完整的子程序和函數,他們被稱爲模塊過程。
過程被當作模塊的一部分進行編譯,並且通過在程序單元中使用包含模塊名的USE語句,從而可以在模塊過程在程序單元中有效。包含在模塊中的過程必須跟在模塊的數據聲明後面,前面加上CONTAINS語句。
Fortran函數
兩種不同類型的函數:內部函數和用戶自定義函數。
用戶自定義Fortran函數的通用格式如下:
...
(Declaration seciton must declare type of name)
...
(Execution section)
...
name=expr
RETURN
END FUNCTION [name]
用戶自定義函數的類型聲明可以採用兩種等價格式之一來完成:
INTEGER FUNCTION my_function(i,j)
或
FUNCTION my_function(i,j)
INTEGER::my_function
過程作爲參數傳遞給其他過程
只有在調用和被調用函數中,才能被聲明爲外部量時,用戶自定義函數纔可以當作調用參數傳遞。當參數表中的某個名字被聲明爲外部變量,相當於告訴編譯器在參數表章傳遞的是獨立的已編譯函數,而不是變量。
用EXTERNAL屬性或者EXTERNAL語句可以聲明函數爲外部的,EXTERNAL屬性像其他屬性一樣包括在函數聲明語句中。
子程序可以作爲調用參數傳遞給過程。
數組的高級特性
二維數組
- 聲明二維數組
例如:REAL,DIMESION(3,6)::sum
INTEGER,DIMESION(0,100,0,20)::hist
CHARACTER(len=6),DIMESION(-3,3,10)::counts
- 二維數組的存儲
fortran以列來存儲對象,不是以行的順序(c/c++)來存儲。 - 初始化二維數組
- 用賦值語句對二維數組初始化
用循環語句賦值(DO END DO)或者RESHAPE函數
RESHAPEh函數格式:output=RESHAPE(array1,array2)
array1包含了要在改變結構的數據,array2描述新結構的一維數組。array2中的元素個數是輸出數組的維數,array2數組中的元素值是每個維度的寬度。 - 用類型聲明語句對二維數組初始化
也要使用RESHAPE函數 - 用READ語句初始化二維數組
如果在一條READ語句的參數列表中出現了一個沒有下標的數組名,程序將會爲數組中的所有元素讀取數值,這些數值將會按照數組元素在計算機內存中的邏輯順序爲數組賦值。
- 用賦值語句對二維數組初始化
5.整數數組的操作和部分數組
只要兩個數組一直,就可以在數學運算和賦值語句中使用。
可以使用下標三元組或者下標向量從二維數組中選取部分數組,a(:1)選用的部分數組對應的是數組的第一列,a(1:)選用的部分數組是數組的第一行。
多維數組
爲n維數組分配內存採用的方式是二維數組以列序分配的方式擴展。
對數組使用fortran內置函數
- 查詢內置函數
函數名稱和調用序列 | 用途 |
---|---|
ALLOCATED(ARRAY) | 判斷可分配數組的分配狀態 |
LBOUND(ARRAT,DIM) | 如果缺少DIM,返回所有的ARRAY下界,如果給出了DIM,返回指定的ARRAY下界 |
SHAPE(SOURCE) | 返回數組SOURCE結構 |
SIZE(ARRAY,DIM) | 如果給出了DIM返回指定維度的ARRAY的寬度,否則返回數組中元素的總個數 |
UBOUND(ARRAY,DIM) | 如果缺少DIM,返回所有的ARRAY上界,如果給出了DIM,返回指定的ARRAY上界 |
加掩碼的數組賦值:WHERE語句
WHERE結構常用格式: [name:] WHERE(mask_expr1)
Array Assignment Statement(s)
ELSEWHERE (mask_expr2) [name]
Array Assignment Statement(s)
ELSEWHERE [name]
Array Assignment Statement(s)
END WHERE [name]
FORALL結構
該結構允許一系列操作用於數組中部分元素,且是逐個用到數組元素上的。被操作的數組元素可以通過下標索引和通過邏輯條件進行選擇。
格式如下:
[name:] FORALL(in1=triplet1[,in2=triplet2,…,logical_expr])
statement1
statement2
…
statement3
END FORALL [name]
FORALL語句中的每個索引都是通過下標的三元組形式來指定的。subscript_1:subscript_2:strid
subscript_1是索引的開始值,subscript_2是結束值,stride是增量值。
- fortran95在類型聲明語句中使用ALLOCATABLE屬性來聲明動態分配內存的數組,使用ALLOCATE語句實際分配內存,當程序使用完內存之後,使用EDALLOCATE語句釋放內存。
REAL,ALLOCATABLE,DIMENSION(:,:)::arr1
數組實際的大小,聲明中使用冒號作爲佔位符。
用冒號來代表它維度的數組稱爲預定義結構數組。
執行程序的時候,數組的實際大小通過ALLOCATE語句來指定。
ALLOCATE語句格式如下:ALLOCATE(list of arrays to allocate,STAT=status)
STAT=子句是可選的,出現了,將返回一個整數狀態值。分配成功狀態爲0,失敗出現一個正數。
Fortran提供一個邏輯型內置函數ALLOCATED(),允許程序在使用數組之前先測試它的分配狀態。
過程的附加特性
給子程序和函數傳遞多維數組
多維數組可以像一維數組那樣傳遞給子程序或者函數。爲了能夠正確的使用數組,子程序或者函數需要直到數組的維數和每一維度的寬度。
1. 顯式結構的形參數組
將數組或數組中的每一維度的取值返回傳遞給子程序,範圍值用於在子程序中聲明數組的大小。
2. 不定結構的形參數組
在子程序中聲明所有的形參數組爲不定結構的形參數組。聲明不定結構的形參數組,數組中的每個下標都用冒號來代替。只有子程序或者函數有顯示接口,才能使用這種數據。
save屬性和語句
save在調用過程之間不修改保存的局部變量和數組
SAVE屬性出現在類型聲明語句中,在調用過程間,任何一個用SAVE屬性定義的局部變量都會被保存,而不改變。
如果一個過程需要局部變量的值在連續調用時不被修改,那麼應該在變量的類型聲明語句中使用SAVE屬性。或者在SAVE語句中包含該變量或者在變量的類型聲明語句中初始化它。