fortran小結


FORTRAN是英文“FORmula TRANslator”的縮寫,譯為“公式翻譯器”,它是世界上最早出現的計算機高級程序設計語言,廣泛應用於科學和工程計算領域。FORTRAN語言以其特有的功能在數值、科學和工程計算領域發揮着重要作用。

早在1951年,美國IBM公司約翰·貝克斯(John Backus)針對匯編語言的缺點着手研究開發FORTRAN語言,並於1954年在紐約正式對外發布。稱約翰·貝克斯提出的FORTRAN語言為FORTRANⅠ,FORTRANⅠ雖然功能簡單,但它的開創性工作,在社會上引起了極大的反響。到1957年第一個FORTRAN編譯器在IBM704計算機上實現,並首次成功運行了FORTRAN程序

在1958年,對FORTRANⅠ進行了擴充和完善,引進了子函數等概念,推出了商業化的FORTRANⅡ版本。之后,FORTRAN語言發展迅速,多種版本相繼在其它計算機上實現。

 

符:Fortran不區分大小寫

Fortran 格式:自由格式和固定格式。Fortran程序代碼擴展名為:*.For 或*.F的文件就是指固定格式;以*.F90為擴展名的文件,就是自由格式。

à固定格式:規定了程序代碼每一行中每個字段的意義。第7~72個字符,是可以用來編寫程序的字段。每一行的前5個字符只能是空格或數字,數字用來作為“行代碼”。每一行的第6個字符只能是空格或“0”以外的字符。

第1個字符

如果是C、c或者星號*,這行文本會被當成說明批注,不會被編譯

第1~5個字符

如果是數字,就是用來給這一行程序代碼取個代號。不然只能是空格

第6個字符

如果是“0”以外的任何字符,表示這一行程序會接續上一行

第7~72個字符

Fortran程序代碼的編寫區域

第73個字符之后

不使用,超過的部分會被忽略,有的編譯器會發出錯誤信息

à自由格式:嘆號(!)后面的文本都是注釋。 每行可以編寫132個字符。行號放在每行程序的最前面。 一行程序代碼的最后如果是符號&,代表下一行程序會和這一行連接;如果一行程序代碼的開頭是符號&,代表它會和上一行程序連接。

 

Fortran的數據類型

à整型(Integer)    à浮點數(Real)   à復數(Complex)    à字符(Character)

à邏輯判斷(Logical)—True or False

Remark: Visual Fortran安裝好后,默認的安裝目錄C:\Program Files\Microsoft Visual Studio\DV98\bin下有一個Bitviewer程序可以用來表看各種數據格式實際在內存中的二進制數據。

 

Fortran的數學表達式

()(括號)、**(乘冪)、*(乘法)or /(除法)、+(加法) or –(減法)à優先級(高à低).

 

輸入(Write)輸出(Print)命令

Fortran程序通常以Program描述來開頭,Program后面還要接一個自定義的程序名稱(這個名稱可以完全自定義,不需要和文件名有任何關系)。Fortran程序最后還要有End描述,表示程序代碼寫到這一行結束。

Write(*,*)命令:括號中的兩個星號都有各自的意義,第一個星號代表輸出的位置使用默認值,也就是屏幕,第二個星號則代表不特別設置輸出格式。

終歸一句話,Write這個命令的最簡單用法,就是在括號中掛上兩個星號,再把所要輸出的字符串用兩個雙引號引起來放在后面。

E.g.:write (*,*) “Hello, Acuzio!”   à 完整的寫法 write(Unit = *, FMT=*) “Hello, Acuzio!”

Write命令注意:

l 每一次執行Write命令后,會自動切換到下一行來准備做下一次的輸入

l 因為雙引號是用來“輸出”字符串的,所以想要輸出雙引號時,要連用兩個雙引號。

l Fortran90可以使用雙引號或單引號來封裝字符串,Fortran77標准中只能使用單引號,不過大部分的Fortran77編譯器還是可以接受雙引號。

STOP命令:是終止程序的意思,它可以出現在程序的任何地方,程序執行到這個命令就會中止。除非必要,不要把Stop命令使用在主程序結束之外的其他地方。因為一個程序,如果有太多的終止點會容易出錯。

把上面例子中用Print命令,程序執行的結果是一樣的àPrint *, ”Hello, Acuzio!”

Print的用法和write大致上相同,只是print后面不使用括號,而且只有一個星號。這個星號的意義是不限定輸出格式。Print和Write的不同處就在於少了Write的第一個星號,也就是少了賦值輸出位置的能力,Print命令只能針對屏幕來使用。建議盡量使用Write來做輸出的工作,因為如果日后想把程序的輸出轉換到其他地方,例如轉換到文件中,使用Write命令的程序改寫起來比較容易,只有把UNIT值指到另一個輸出位置就行了。

Integer:Integer(kind = 4) a            Integer *4 a              Integer(4) a

其中kind=4、*4、(4)都是賦值要使用4個bytes來存放整數的意思。

聲明變量的原則

l 變量的名稱以使用英文字母為原則,可以內含下划線或數字,但前綴必須是英文字母

l 變量名字的長度,在77標准中最起碼支持6個字符長,90標准中最起碼支持31個字符長。也就是說在Fortran77中變量長度最后是在1~6之間,在Fortran90中變量長度則最后是在1~31之間

l 變量名稱最好不要和Fortran的執行命令同名,也不能和主程序的名稱或是前面聲明過的變量同名。

l 程序中辨認變量時,不會區分它的大小寫

Fortran90的聲明語法多了一些變化,它可以在類型的后面先寫兩個冒號“::”,再寫上變量的名稱

 

Real

Real(kind=4)表示單精度。Real(kind=8)表示雙精度

 

Complex

Fortran中聲明復數的方法:Complex a

復數是有實部和虛部兩個部分組成,而Fortran中保存這兩個數字的方法是用兩個浮點數來保存,所有復數也可以分成單精度及雙精度兩種類型。

要設置一個復數數值的方法如下:a=(x,y) !x為實部,y為虛部,當a=(3.2,2.5)時,表示a=3.2+2.5i

 

Character:

聲明:character(len=10) a     character(10)a                   character*10 a         character*(10) a

字符串長度需要多少字符,就賦值多少數字給它

Program ex

 Character(len=20) string

 String = “Good morning.”

 Write(*,*) string

 String(6) = “evening.” !重新設置從第六個字符之后的字符串

 Write(*,*) string

end

上例中 string(1:2) = “GO”      !字符串最前面兩個字符會變成GO

String(13:13)=”!”     !字符串的第13個字符會變成嘆號

用(//)可以把前后兩個字符串連接起來

Fortran有關字符串運行的函數

Char(num)

返回計算機所使用的字符表上,數值num所代表的字符

IChar(char)

返回所輸入的char字符在計算機所使用的字符表中所代表的編號,返回值是整數類型

Len(string)

返回輸入字符串的聲明長度,返回值是整數類型

Len_Trim(String)

返回字符串去除尾端空格后的實際內容長度

Index(string,key)

所輸入的String和key都是字符串。這個函數會返回key這個“子字符串”在“母字符串”String中第一次出現的位置

Trim(string)

返回把string字符串尾端多余空格清除過后的字符串

 

Logical

邏輯變量並賦值。Logical a = .true.

設置邏輯變量的方法:當設置“真”值或者“假”值,請注意要在true和false的前后要加上兩個點

 

輸入命令Read

Read(*,*)                   read命令在使用時和write一樣,都有兩個星號。代表的意義也是差不多的,第一個星號代表輸入的來源使用默認的設備(也就是鍵盤),第二個星號代表不指定輸入格式

格式化輸入輸出(Format

Program ex

 Integer a

 a = 100

 write(*,100) a !使用行代碼100,也就是第五行的格式來輸出變量a

 100 format(I4) !最前面的100是行代碼,把這一行程序代碼給一個編號

End

Format格式

Aw

以w個字符寬來輸出字符串

BN

定義文本框中的空位為沒有東西,在輸入時才需要使用

BZ

定義文本框中的空位代表0,在輸入時才需要使用

Dw.d

以w個字符寬來輸出指數類型的浮點數,小數部分占d個字符寬

Ew.d[Ee]

以w個字符寬來輸出指數類型的浮點數,小數部分占d個字符寬,指數部分占e個字符

ENw.d[Ee]

以指數類型來輸出浮點數

ESw.d[Ee]

以指數類型來輸出浮點數

Fw.d

以w個字符寬來輸出浮點數,小數部分占d個字符寬

Gw.d[Ee]

以w個字符寬來輸出整數,最少輸出m個數字

Iw[.m]

以w個字符寬來輸出整數,最少輸出m個數字

Lw

以w個字符寬來輸出T或F的真假值

nX

把輸出的位置向右跳過n個位置

/

代表換行

在沒有更多數據時結束輸出

kP

K值控制輸入輸出的SCALE

Tn

輸出的位置移動到本行第n列

TLn

輸出的位置向左相對移動n列

TRn

輸出的位置向右相對移動n列

SP

在數值為正時加上“正號”

SS

取消SP

Fortran 90添加的格式

Bw[.m]

把整數轉換成二進制來輸出、輸出會占w個字符寬,固定輸出m個數字。m值可以不給定

Ow[.m]

把整數轉換成八進制來輸出,輸出會占w個字符寬,固定輸出m個數字。m值可以不給定

Zw[.m]

把整數轉換成十六進制來輸出,輸出會占w個字符寬,固定輸出m個數字。m值可以不給定

 

變量名稱的取名策略:變量的名字中可以使用的字符集包括英文的26個字母、0~9這10個數字以及下划線“_”,不過前綴必須是英文字母。變量名稱的長度限制隨着各家編譯器的不同而不同,Fortran 標准規定最少要支持到6個字符,Fortran90則最少要支持到31個字符

 

Implicit

Fortran 標准中有一項不太好的功能,它的變量不一定要經過程序聲明才能使用,編譯器會根據變量的第一個字母來自東決定這個變量的類型。第一個字母為I、J、K、L、M、N的變量會被視為整數類型,其他的變量則會被當成浮點數來使用。

Implicit命令的功能是用來設置“默認類型”。所謂的默認類型,是指Fortran不經過聲明,由第一個字母來決定變量類型。可以經過Implicit描述來決定哪些字母開頭的變量會自動使用某種類型

Implicit integer (A,B,C) !A、B、C開頭的都被視為整型數

Implicit integer(A-F,I,K) !A到F及I、K開頭的變量都視為整型數

Implicit real(M-P) !M到P開頭的變量都視為浮點數

Implicit none !關閉默認類型功能,所有變量都要事先聲明

 

常數的聲明方法(Parameter

Program ex

Implicit none

Real ::pi

Parameter(pi = 3.14129)

Write(*,”(F4.2)”) sin(pi/6)

end

在Fortran90里,Parameter可以作為形容詞,和變量的聲明同時寫在一起

Real, parameter ::pi=3.14159 !這里pi前面的冒號不能省,和上面代碼不同(上面的可以省略)

 

設置變量的初值

變量內容並不一定要在程序執行時才設置,可以在聲明時同時給予初值。在Fortran90偶那個,在設置變量初值時,直接把數值寫在聲明的變量后面就行了。使用這個方法來設置初值是,不能省略聲明中間的那兩個冒號(Fortran90)

在fortran77中則要使用Data命令設置初值

Fortran 90

Fortran 77

program ex90

implicit none

integer ::a=1

real ::b=2.0

complex ::c=(1.0,2.0)

character (len=20) ::str="Hello Acuzio!"

write (*,*) a,b,c,str

end

program ex77

implicit none

integer a

real b

complex c

character (len=20) str

data a,b,c,str/1,2.0,(1.0,2.0),’Hello ‘/

write (*,*) a,b,c,str

end

 

等價聲明(equivalence)

把兩個以上的變量,聲明它們使用同一個內存地址,就是“等價聲明”。使用同一個內存位置的變量,只要改變其中一個變量,就會同時改變其他變量的數值

Integer a,b

Equivalence(a,b)

 

Fortran 90 的自定義數據類型

使用關鍵字:type

Type ::person

 Character(len=30) ::name

 Integer ::age

 Integer ::length

 Integer ::weight

End type person

Type(person) ::a !聲明一個person類型的變量

a%name !引用person中的name

 

Kind的使用

Kind描述如果搭配上一些Fortran90的庫函數,可以增加程序代碼的“跨平台”能力

Fortran 90提供庫函數來判斷所要記錄的數值值域范圍所需要的kind值

Selected_int_kind(n) : 返回如果想要記錄n位整數時,所應聲明的kind.返回-1時,表示無法提供所想要的值域范圍

Selected_real_kind(n,e) : 返回如果想要能夠記錄具有N位有效位數、指數達到e位的浮點數所需要的kind值。返回-1表示無法滿足所要求的有效位數、返回-2表示無法滿足所要求的指數范圍、返回-3表示兩者都無法滿足

IF基本用法

If(邏輯判斷式) then

……

End if

If(邏輯判斷式) then

……

Else

……

End if

 

邏輯運算符:

Fortran 90

 

Fortran 77

==

判斷是否“相等”

 

.eq.

判斷是否“等於”

/=

判斷是否“不相等”

 

.ne.

判斷是否“不等於”

判斷是否“大於”

 

.gt.

判斷是否“大於”

>=

判斷是否“大於或等於”

 

.ge.

判斷是否“大於或等於”

判斷是否“小於”

 

.lt.

判斷是否“小於”

<=

判斷是否“小於或等於”

 

.le.

判斷是否“小於或等於”

 

 

邏輯判斷式

.and.

交集,如果兩邊的表達式都成立,整個表達式就成立

.or.

並集,兩邊的表達式只要有一個成立,整個表達式就成立

.not.

邏輯反向,如果后面的表達式不成立,整個表達式就成立

.eqv.

兩邊表達式的邏輯運算結果相同時,整個表達式就成立

.neqv.

兩邊表達式的邏輯運算結果不同時,整個表達式就成立

 

多重判斷

If(條件1) then

……

Else if(條件2) then

Else

……

End if

浮點數及字符的邏輯運算

使用浮點數來做邏輯運算時,要避免使用“等於”的判斷。因為使用浮點數做計算時,有效位數是有限的,難免會出現計算上的誤差,理想中的等號不一定會成立。要使用浮點數來做“等於”的邏輯判斷時,最好用其他方法來取代(ABS這個函數是取絕對值。使用誤差小於某一個值來進行判斷)

 

Select case語句

Select case(變量)

Case(數值)

……

Case(數值2)

……

Case default

……

End select

在case里的冒號前后放兩個數值時,代表在這兩個數值范圍中的所有數值

Remark:

l Select case只能使用整數(integer)、字符(character)及邏輯變量(logical),不能使用浮點數及復數

l 每個case中所使用的數值必須是固定的常量,不能使用變量

Pause, continue, stop

Pause的功能就跟它的字母意義相同,程序執行到pause時,會暫停執行,直到用戶按下enter鍵才會繼續執行。

Continue 無實際用途

Stop 結束程序執行

Fortran 90的庫中,IAND用來做二進制的AND計算,IOR用來做二進制的OR計算

DO循環

Integer, parameter ::index = 1

Integer, parameter ::counts = 100

Do index,counts,1

……

End do

Real,parameter ::weight =45.0 !答案

Real,parameter ::e=0.001 !誤差

Real ::guess

Do while(abs(guess-weight)>e)

Write(*,*) “Weight”

Read(*,*) guess

End do

循環控制:

Cycle和exit

Cycle 命令可以略過循環的程序模塊中,在cycle命令后面的所有程序代碼,直接跳回循環的開頭來進行下一次循環

Exit 功能:可以直接“跳出”一個正在運行的循環

署名循環

循環還可以取“名字”,這個用途是可以在編寫循環是能明白地直到End do這個描述的位置是否正確,尤其是在多層循環當中。署名的循環也可以配合Cycle、exit來使用。

數組(Array

數組的聲明方法:Datatype name(size)

賦初值:

integer A(5)

Data a /1,2,3,4,5/

Integer a(5)

Data a /5*3/ !5個3

Integer A(5)

Integer i

Data(A(i),i=2,4) /2,3,4/

!這是一個隱含式循環,I會從2增加到4,依照順序到后面取數字。初值設定結果為A(2)=2、A(3)=3、A(4)=4,A(1)和A(5)沒有設定

 

Fortran 90隱含式循環的功能可以更強大

Integer ::a(5)=(/(I,I=1,5)/) !設置結果:a(1)=1,a(2)=2,a(3)=3,a(4)=4,a(5)=5

 

Where

Where是Fortran95添加的功能,它也是用來取出部分數組內容進行設置

Forall

Forall是fortran95添加的功能。間斷地說,它也可以看出是一種使用隱含循環來使用數組的方法,不過它的功能可以做得更強大。

Integer i

Integer ::a(5)

Forall(i=1:5)

A(1)=5

End forall

Forall詳細語法為

Forall(triplet1[,triplet2[,triplet3……]],mask)

……

End forall

其中mask用來做條件判斷

Fortran90 可以聲明可變大小數組

Integer,allocatable ::a(:) !聲明一個可變大小的一位數組

Integer ::students

Read(*,*) students

Allocate(a(students)) !配置內存空間

計算機的內存是有限的,當然也就不能無限制地去要求空間來使用。所以allocate命令在內存滿載是,有可能會要求不到使用空間。Allocate命令中可以加上stat的文本框得知內存配置是否成功

Allocate(a(100),stat=err)                  !err是事先聲明號的整型變量,做allocate這個動作時會經有stat這個敘述傳給err一個數值,如果err等於0則表示allocate數組成功,而如果err不等於0

則表示allocate數組失敗

Deallocate(a) 表示刪除分配的內存

跟allocate相關的函數還有allocated,它用來檢查一個可變大小的矩陣是否已經配置內存使用,他會返回一個邏輯值

 

If(.not. allocated(a))then

Allocate(a(5))

End if

函數

子程序(subroutine)的使用

子程序代碼以subroutine開頭,它同樣要取一個名字,以end或end subroutine來結束。嚴格地講,end subroutine后還可以再接上這個子程序的名字

program ex

implicit none

integer ::a=1

integer ::b=2

call add(a,b)

end

 

subroutine add(first,second)

implicit none

integer ::first,second

write(*,*) first+second

return

end

函數的調用

program ex

implicit none

real ::a=5,b=4

real,external ::add !聲明add是函數而不是變量

!調用函數add,調用函數不必使用call命令

write(*,*) add(a,b)

end

 

function add(a,b)

implicit none

real ::a,b

real ::add

add =a+b

return

end

全局變量

Common是fortran77使用“全局變量”的方法,它用來定義一塊共享的內存空間

program ex

implicit none

integer ::a,b

common a,b !定義a,b是全局變量中的第1及第2個變量

a=1

b=2

call showCommon()

end

 

subroutine showCommon()

implicit none

integer ::num1,num2

common num1,num2 !定義num1,num2是全局變量中的第1及第2個變量

write(*,*) num1,num2

return

end

Block data

關於common還有最后要介紹的就是設置初值的方法,common變量不能直接在子程序或主程序中使用data來設置初值,要在block data程序模塊中使用data命令來設置初值

program ex

implicit none

integer ::a,b

common a,b !a,b放在不署名的全局變量空間中

integer ::c,d

common /group1/c,d !c,d放在group1的全局變量空間中

integer ::e,f

common /group2/e,f !e,f放在group2的全局變量空間中

 

write (*,"(6I4)") a,b,c,d,e,f

end

 

block data

implicit none

integer a,b

common a,b !a,b放在不署名的全局變量空間中

data a,b /1,2/ !設置a,b的初值

integer c,d

common /group1/c,d !c,d放在group1的全局變量空間中

data c,d /3,4/ !設置c,d的初值

integer e,f

common /group2/e,f !e,f放在group2的全局變量空間中

data e,f /5,6/   !設置e,f的初值

end block data

變量的生命周期

在聲明中加入save 可以拯救這些變量、增加變量的生命周期、保留住所保存的數據。這些變量可以在程序執行中永久記憶住上一次函數調用時所被設置的數值

program ex

implicit none

call sub()

call sub()

call sub()

end

 

subroutine sub()

implicit none

integer ::count = 1

save count !賦值count變量會永遠活着,不會忘記它的內容

write(*,*) count

count = count + 1

return

end

在Fortran 90 中,可以把save跟聲明寫作同一行

Integer ,save ::count=1

傳遞函數

傳遞參數時,除了傳遞數字、字符等等數據之外,還可以把一個函數名稱當成參數傳送出去

program ex

implicit none

real,external ::func !聲明func是個自定義函數

real,intrinsic ::sin !聲明sin是庫函數

 

call ExecFunc(func) !輸入自定義函數func

call ExecFunc(sin) !輸入庫函數sin

end

 

subroutine ExecFunc(f)

implicit none

real,external ::f !聲明參數f是個函數

write(*,*) f(1.0) !執行輸入函數f

return

end

 

real function func(num)

implicit none

real ::num

func = num*2

return

end

關鍵字Intrinsic表明所聲明的sin是fortran的庫存函數,而不是一個變量


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM