Fortran 95快速學習筆記

基本語法

1.Fortran對大小寫不敏感。使用語句行來表示語句的開始和結束而不是分號。
2.長語句需要分兩行時需要在第一行的行尾使用&來結束
3.可以使用1~99999之間的任意數字放在行Fortran語句行的行首作為該語句的語句標號,可以在程序的其他地方通過該數字引用這條語句,語句標號必須是惟一的。
4.感嘆號!開始到行尾的字符為注釋,將被編譯忽略。注釋可以放在程序的任何位置。
5.PROGRAM語句對編譯器指定程序的名字,名字命名類似C,但必須以字母開頭,該語句必須放在第一個語句行,相當于指定程序的執行入口
6.WRITE表示向輸出寫入數據,兩個參數與READ中的意思相同。eg:

WRITE (*,*) output_list
PRINT *, output_list

二者等價
7.READ為從輸入讀取數據,其中的第一個參數指明從哪個輸入/輸出單元讀入數據,星號表示標準輸入,第二個參數指明讀入數據的格式,星號表示使用表控輸入,即意味著為變量列表中的變量類型決定輸入數據需要的格式??。eg:

READ (*,*) input_list !將數據讀入的變量列表中

每一條READ將始終從一個新行開始讀取,如果上一行輸入有剩余則會自動被清除
8.STOP告訴計算機停止運行,END PROGRAM告訴編譯器程序中不再有語句需要編譯,當STOP緊挨著END PROGRAM語句時,它是可選的。
9.Fortran程序書寫風格:

1.保留字都大寫
2.程序的變量用小寫字母表示
3.常量名最好也使用大寫,如PI(3.14159)
4.名字中的下劃線出現在兩個字之間

10.Fortran的語句分為可執行語句(executable)和不可執行語句(unexecutable),聲明即是不可執行語句,應放在程序的開頭
11.IMPLICIT NONE語句表示使Fortran中默認提供輸入值類型的功能失效,該語句應該出現在PROGRAM語句之后和類型聲明語句之前。默認輸入值類型是指在Fortran中,變量可以不經定義直接使用,而變量的類型是以變量名的第一個字母來區分的,例如IMPLICIT real*8(A-H,O-Z)即表A到H開頭的變量類型都是浮點型。使用IMPLICIT NONE之后而所有變量必須在使用之前定義。

基本數據類型及其運算

1.Fortran有5個內置的數據類型,其中三個對數字有效(INTEGER, REAL, COMPLEX),一個邏輯相關(LOGICAL),另一個是字符串(CHARACTER)。
2.字符文本可以使用單引號’,也可以使用雙引號”
3.有兩種方式可以定義變量的類型:默認式和顯式。如果在程序中沒有明確指定變量類型,那么就是默認式定義變量類型,默認方式為:任何以字母I,J,K,L,M或N開頭變量名都假定為INTEGER,其他字母開頭的變量名假定為REAL,注意Fortran對大小寫不敏感。例如默認情況inc的變量為整形,big為實型。
IMPLICIT NONE語句將使默認變量類型功能失效。
顯式聲明方式為INTEGER :: var1 [, var2, var3, ...],其中[]表示其中的內容可選,只聲明不初始化的話雙冒號也是可選的。
4.字符串的聲明方式:

CHARACTER(len=10) :: first, last !聲明兩個長度為10的字符變量
CHARACTER :: initial !聲明一個長度為1的字符變量  
CHARACTER(15) :: id !id長度為15

5.使用PARAMETER屬性創建常數類型,方式為type, PARAMETER :: name=value [, name2=value2, ...]其中type的類型可以是整形,實型,邏輯型或字符型。eg:

REAL , PARAMETER :: PI = 3.141593

6.**表示指數運算。
7.Fortran95/2003中含有5個強制類型轉換函數:

INT(X) 將REAL類型的X轉換其整數部分
NINT(X) 返回REAL類型的X的四舍五入結果
CEILING(X) 大于或等于X的最小整數值,X為REAL
FLOOR(X) 小于或等于X的最大整數值,X為REAL
REAL(I) 將整數轉換為實數

9.邏輯數據類型只有兩個可能的值:true和false,分別對應的內置邏輯常數是.TRUE.和.FALSE.(注意兩連的句點),邏輯變量聲明方式LOGICAL :: var1, [, var2, var3, ...],所有聲明都應該放在第一條執行語句之前,PROGRAM語句之后。
10.關系運算符中/=表示不等于,對應的舊形式為.NE.,所有運算符:

新形式:==   /=     >    >=    <    <= 
舊形式:EQ.  .NE.  .GT.  .GE. .LT. .LE.

11.組合邏輯運算符:

    .AND. 邏輯與
    .OR. 邏輯或
    .NOT. 邏輯非
    .EQV. 邏輯等值,相同為真
    .NEQV. 邏輯非等值,不相同為真

12.當邏輯變量出現在以READ開頭的語句中時,相應的輸入值必須以T或F開頭的一個或一組字符,相應的值被設置為.TRUE.或.FALSE,輸入其他字符開頭將產生運行時錯誤。當邏輯變量或表達式出現在以WRITE開頭的語句中時,相應輸出將為單個字符T或F。
14.Fortran中的數組首元素是從1而不是0開始,子串抽取與python一樣。例如若str=’12345’,則str(2:4)為234。
15.連接操作符//可以將兩個子串連接成一個大串。
16.可以在定義類型里手動指定變量所占用的字節大小。方法如下:TYPE(kind) :: var,其中kind為正整數,表示該變量所占字節數,如果不指定默認為長整型4或浮點型的8。例如INTEGER(4) :: var,var為占用4個字節的整型。Fortran90之前的編譯器聲明方式為INTEGER4 var*
16.real(8) var var = 0.0_8 表示為var初始化值為0.0,且占8個字節。

控制語句

1.IF語句與C中類似,形式如下:

[名稱: ]IF (logical_expr) THEN
  statement 1
  statement 2
ELSE IF (logical_expr_2) THEN [名稱]
  statement 1
  statement 2
ELSE [名稱]
  statement 1
  statement 2
  ...
END IF [名稱]

其中IF THEN必須在同一行,且其下面一行必須緊跟可執行語句,ELSE,ELSE IF和END IF也必須獨占一行,END IF前面面不能有行號
其中名稱是可選的,但如果IF前面有名稱那么END IF后面也必須有,且同名
當IF語句塊中只有一行語句時,等價于

IF (logical_expr) expression

2.當嵌套使用IF語句時,最好為其命名
3.SELECT CASE語句類似于C中每個case都帶有break語句的switch,用法如下:

[name: ]SELECT CASE (case_expr)
CASE (case1) [name]
  statement 1
  statement 2
  ...
CASE (case2, case3, case4) [name]
  statement 1
  statement 2
  ...
CASE DEFAULT [name]
  statement 1
  statement 2
  ...
END SELECT [name]

其中case_expr可以是任意的整數、字符或邏輯表達式。對應的每個子case必須是整數、字符或邏輯數值,或數值范圍,所有子case必須相互獨立。其中數值范圍是指以冒號隔開的一個范圍,與python中的范圍表示方式一樣,如(1:10)表示1~10。
4.DO循環:

DO 
  ...
  IF (logical_expr) EXIT
  ...
END DO
5.DO WHILE循環:

DO WHILE (logical_expr)
  statement 1
  ...
  statement n
END DO

6.迭代DO循環,類型C中的for循環:

DO index=istart,end,incr
  statement 1
  ...
  statement n
END DO

其中index是一個整數變量,作為循環計數器使用,整數istart,iend和incr分別表示計數起始值,結束值和步長,它們可以是常量、變量或表達式,當incr省略時,步長默認為1。如果indexincr <= iendincr。
7.控制語句中的CYCLE相當于C中的continue,EXIT相當于C中的break。
8.循環語句也可以被命名,規則與IF命名一樣。

IO操作

1.格式化的WRITE輸出:

WRITE (*,100) i, result
100 FORMAT (' The result for iteration ', I3, ' is ', F7.3)

意思是輸出i和result,使用100做為語句標號,相當于一個大的占位符,用于代替WRITE語句的第二個控制輸出方式的參數,輸出結果即是字符串正常輸出,帶有占位符的地方,使用對應值替換。例如I3表示以占用3個字符寬度的方式輸出INTEGER類型的i,F7.3表示以占用7個字符寬度且保留小數點后3位方式輸出REAL類型的result。

2.以下三個輸出結果是等價:

WRITE (*, 100) i, x     !使用FORMAT控制格式
100 FORMAT (X, I6, F10.2)

CHARACTER (len = 20) :: string !使用字符變量控制格式
string = '(1X, I6, F10.2)'
WRITE (*, string) i, x

WRITE (*, '(1X, I6, F10.2)') i, x  !在字符常量中的格式

string可以代替括號內
3.老式的Fortran編譯器的格式控制字符中的第一個字符將起到控制輸出格式的作用,所以上面1例中FORMAT的內容以空格開頭,但在Fortran2003之后的版本中并沒有這個限制。具體控制字符的作用如下:

1 跳轉到新頁
空格 單行間距
0 雙行間距
沒有間距(在前一行上打印)

下面的兩句是等價的,都表示在新的一頁的開頭打印輸出

WRITE (*,"('1', 'Count = ', I3)") icount
WRITE (*,"('1Count = ', I3)") icount

4.控制格式描述的符號如下

    c 列號
    d 實數輸入或輸出小數位右邊的位數
    m 要顯示的最小位數
    n 要跳過的空格數
    r 重復計數——一個描述符或一組描述符的使用次數
    w 域寬——輸入或輸出使用的字符數

5.常見的輸出控制格式:

    整數輸入——I描述符的一般格式為rIw或rIw.m
    實數輸出——F描述符一般格式為rFw.d
    實數輸出——E描述符一般格式為rEw.d
    真正的科學計數輸出——ES描述符一般格式為rESw.d
    邏輯輸出——L描述符一般格式為rLw
    字符輸出——A描述符一般格式為rA或rAw
    X描述符用于在緩沖區中插入間距,用法為nX
    T描述符用于在緩沖區中跳過特定列,用法為Tc,其中c為要轉到的列號
    改變輸出行——斜線(/)描述符,類似C中的\n,用于換行

舉例,以下兩條語句是等價的:

320 FORMAT ( X, I6, I6, F10.2, F10.2, I6, F10.2, F10.2 )
320 FORMAT ( X, I6, 2(I6, F10.2) )

當格式控制字符中的寬度無法表示所要輸出的數字時,不像C中直接全部輸出,Fortran會輸出為星號*,例如格式控制字符I1,輸出10的時候,會輸出一個*
6.輸出格式要與輸出變量嚴格對應,否則會有運行時錯誤
7.READ的讀取格式控制與WRITE一一對應
8.Fortran的I/O讀寫語句的第一個參數就是用于指定讀寫設備。該位置的星號即表示標準輸出或輸入,如果使用其他設備則需要指定I/O單元號,單元號必須為整數類型。
9.常用的I/O語句:

    OPEN 將指定的文件與指定的I/O單元號關聯
    CLOSE 取消指定的文件與指定的I/O單元號的關聯
    READ 從指定的I/O單元讀取數據
    WRITE 向指定的I/O單元寫入數據
    REWIND 移動到文件的開頭
    BACKSPACE 在當前打開的文件中向后移動一個位置

10.OPEN用法為OPEN (open_list),期中open_list包含一組子句,分別指定I/O單元代號、文件名和關于如何存取文件的信息,這些列表使用逗號隔開。
11.open_list中最重要的六項內容:

    UNIT=int_expr 指明與文件關聯的I/O單元代號,int_expr可以是非負的整數值
    FILE=char_expr 指定要打開的文件名,char_expr是一個包含要打開文件的名稱的字符值
    STATUS=char_expr 指定要打開的文件狀態,char_expr為下列值中的一個:'OLD','NEW','REPLACE','SCRATCH'或'UNKNOW'。
    ACTION=char_expr 指定一個文件是以只讀、只寫或讀寫方式打開。char_expr為下列值中的一個:'READ','WRITE'或'READWRITE',如果沒有指定任何操作,則默認以讀寫方式打開。
    IOSTAT=int_var 指定一個整數變量名,打開操作的狀態可以返回到這個變量中。如果OPEN語句成功執行,則返回給這個整數變量的值為0。
    IOMSG=chart_var 指定一個字符變量名,如果發生錯誤,則該錯誤信息將返回給這個變量。如果OPEN語句成功執行,則該變量的內容不變。
示例:
!打開一個名為EXAMPLE.DAT的文件,并將其連接到I/O單元8上
INTEGER :: ierror
OPEN (UNIT=8, FILE='EXAMPLE.DAT', STATUS='OLD', ACTION='READ', &IOSTAT=ierror)  
!以自由格式從文件中讀取值到x,y,z
OPEN (UNIT=8, FILE='INPUT.DAT', STATUS='OLD', IOSTAT=ierror)
READ (8,*)  x, y, z
!以特定的格式向文件OUTPUT.DAT中寫入變量x,y,z的值
OPEN (UNIT=9, FILE='OUTPUT.DAT', STATUS='REPLACE', IOSTAT=ierror)
WRITE (9,100) x, y, z
100 FORMAT (' X = ', F10.2, ' Y = ', F10.2, ' Z = ', F10.2)

12.BACKSPACE和REWIND語句的功能相當于修改文件指針所指向的位置
13.READ在按行讀取文件時會自動跳過空行

數組

1.Fortran中的數組元素從下標1開始,通過小括號()訪問
2.數組聲明方式如下:

!聲明一個含有16個元素的實型數組voltage
REAL, DIMENSION(16) :: voltage
!等價于
REAL :: voltage(16)
!聲明一個含有50個長度為20位字符的數組變量last_name
CHARACTER (len=20), DIMENSION(50) :: last_name

DIMENSION屬性說明被定義數組的大小
3.通過(/…/) 可以構建常量數組,如

(/ 1, 2, 3, 4, 5 /)

構建了一個含有5個整型元素的數組常量
4.數組的初始化可以先聲明然后使用賦值的方式初始化,或者使用數組構建器初始化,也可以通過給數組名賦值將所有元素初始化同一個值,或者在聲明時直接初始化。eg:

REAL, DIMENSION(10) :: array1
DO i = 1, 10
  array1(i) = REAL(i)
END DO
!等價于  
array1 = (/1., 2., 3., 4., 5., ..., 10./)
!等價于
REAL, DIMENSION(10) :: array1 = (/1., 2., 3., 4., 5., ..., 10./)
!將所有的array1初始化為0
array1 = 0

5.可以使用隱式DO循環初始化數組,形式為

(arg1, arg2, ..., index = istart, iend, incr)

,其中arg1, arg2等是每次循環執行時估算的值,隱式DO循環支持嵌套。eg:

!上面聲明并初始化array1的等價形式
REAL, DIMENSION(10) :: array1 = (/ (REAL(i), i=1, 5) /)

6.可以使用以下方式在聲明時指定下標取舍范圍:

!該數組的大小為upper_bound - lower_bound + 1
REAL, DIMENSION(lower_bound : upper_bound)  :: array

7.聲明常量名來作為數組大小:

INTEGER, PARAMETER :: MAX_SIZE = 1000
REAL :: array1(MAX_SIZE)

8.當兩個數組元素類型和大小相同時,對數組名的運算相當于對數組的每個元素分別進行運算,如:

REAL, DIMENSION(10) :: a, b, c
c = a + b !等價于c(i) = a(i) + b(i)

9.可以使用下標三元組或向量下標的形式來使用數組的部分變量,稱為部分數組(section array),三元組的使用方式為subscript_1 : subscript_2 : stride,當stride省略時,表示默認步長為1,當subscript_1省略時默認表示從第一個元素開始,當subscript_2省略時默認到最后一個元素,與python的包前不包后不同,Fortran這種局部數組前后都包。
10.向量下標的使用方式如下:

INTEGER, DIMENSION(5) :: vec = (/1, 6, 4, 1, 9/)
REAL, DIMENSION(10) :: a = (/1., -2., 3., -4., 5., -6., 7., -8., 9., -10./)
!a(vec)的內容是數組[1., -6., -4., 1., 9.]

11.讀寫數組時可以使用隱式DO循環,形式如下:

WRITE (unit, format) ( arg1, arg2, ... , index = istart, iend, incr)
READ (unit, format) ( arg1, arg2, ... , index = istart, iend, incr)
!以下打印前5個元素的方法等價
WRITE (*,100) a(1), a(2), a(3), a(4), a(5)
100 FORMAT (X, 'a = ', F10.2)
!等價于
WRITE (*,100), (a(i), i = 1, 5)
100 FORMAT (X, 'a = ', F10.2)

12.隱式DO循環可以嵌套使用

Fortran過程控制

子程序

1.Fortran的有兩種方式實現調用外部過程,分別是子程序(subroutine)和函數之程序(function subprogram)。子程序通過CALL語句調用,并且可以通過調用參數來返回多個結果。函數子程序則通過在表達式中引入函數名來進行調用,它的結果是單個數值,該值用來為表達式賦值,就像數學中的函數那樣。
子程序

2.子程序的聲明格式如下:

SUBROUTINE subtine_name(argument_list)
  ...
  (Declaration section)
  ...
  (Execution section)
  ...
  RETURN
END SUBROUTINE [name]

其中argument_list中不能附帶參數類型,但在子程序內容的聲明部分必須要為相應的參數聲明類型
子程序就相當于一個獨立的程序,只是可以帶參數,所以在聲明部分的前面同樣需要單獨加上IMPLICIT NONE
3.子程序的調用格式如下:

CALL subroutine_name(argument_list)

4.子程序的參數傳遞方式為傳址傳遞,相當于C語言中傳遞指針,所以子程序會直接修改原變量的值,如果想在子程序內部不對傳遞進來的參數進行修改,可以在聲明部分使用INTENT屬性聲明,相當于在子程序內容將相應參數修改為const類型,eg:

!加法子程序,并改變傳遞進去的某個變量的值
SUBROUTINE add(a, b, c)
  IMPLICIT NONE
  REAL :: a
  REAL, INTENT(IN) :: b !添加IN發生后b將不能作為左值,且不能被修改
  REAL, INTENT(OUT) :: c !添加OUT屬性后,c將可以作為左值,且可以被修改
  c = a + b
  a = 5.0 !調用后原程序對應的變量值將變成5.0,但不能以同樣的方式修改b,否則會編譯報錯
  RETURN
END SUBROUTINE add

調用時參數類型必須一致
5.INTENT的所有屬性:

    INTENT(IN) 形參僅用于向子程序傳遞輸入數據
    INTENT(OUT) 形參僅用于將結果返回給調用程序
    INTENT(INOUT)/INTENT(IN OUT) 形參即用來向子程序輸入數據,也用來將結果返回給調用程序

6.與C中一樣,為子程序傳遞數組時,需要傳遞數組的大小
7.傳遞字符變量給子程序時可以使用*聲明字符變量的長度,當在子程序內容需要使用到字符串的長度時可以使用LEN()函數來獲取字符串長度,聲明方式如下:

SUBROUTINE sample (string)
CHARACTER ( len=* ), INTENT(IN)  :: string

模塊

8.Fortran可以使用模塊來在不同的程序之間共享數據,模塊相當于C中的頭文件,它可以用來共享數據,同樣可以用于共享子程序,聲明方式是使用MODULE,引用方法是使用USE module_name。下面例子說明使用其共享數據。eg:

MODULE shared_data
IMPLICIT NONE
SAVE
INTEGER, PARAMETER :: num_vals = 5 
REAL, DIMENSION(num_vals) :: values
END MODULE shared_data

!使用模塊
PROGRAM test_module
USE shared_data
IMPLICIT NONE
values = 2
CALL sub
END PROGRAM test_module

!SUBROUTINE
SUBROUTINE sub
USE shared_data
IMPLICIT NONE
WRITE (*,*) values
END SUBROUTINE sub

SAVE語句能夠保證在模塊中聲明的數據被保護在不同的過程間的引用中。
sub子程序中的values將全部為2,因為該變量是與主程序共享的

http://annefou.github.io/Fortran/modules/modules.html

9.模塊中需要定義子程序和函數時必須使用關鍵字CONTAINS,這些子程序和過程被稱作模塊過程。eg:

MODULE my_subs
IMPLICIT NONE
(Declare shared data here)
CONTAINS
  SUBROUTINE sub (a, b, c, k, error)
  IMPLICIT NONE
  REAL, DIMENSION(3), INTENT(IN) :: a
  REAL, INTENT(IN) :: b, c
  REAL, INTENT(OUT) :: x
  LOGICAL, INTENT(OUT) :: error
  ...
  END SUBROUTINE sub
END MODULE my_subs

函數

1.Fortran函數是這樣一個過程:它的結果只能是單個數值、邏輯值、字符串或數組之一。有兩種不同類型的函數:內部函數(intrinsic function)和用戶自定義的函數(user-defined function,或函數子程序function subprograms)。其中內部函數即是指Fortran自帶的SIN(X)、LOG(X)等。

2.自定義Fortran函數的通用格式如下:

[TYPE] FUNCTION name (argument_list)
...
(Declaration section must declare type of name)
...
(Execution section)
...
name = expr
RETURN
END FUNCTION [name]

其中,TYPE表示函數的返回值類型,使用IMPLICIT NONE語句時,必須要指名函數的返回類型,如果有使用IMPLICIT NONE語句,那么函數的返回類型將默認使用Fortran的內置規則。RETURN語句只是表示結束本函數,將執行權限歸還給調用函數,所以RETURN并不是必須有。函數的返回值是通過給函數名賦值而實現,所以函數中必須至少有一次讓函數名出現在賦值語句的左側來指定函數的返回值。

2.函數的聲明可以采用以下兩種等價格式之一:

INTEGER FUNCTION my_function(i, j)

FUNCTION my_function(i,j)
INTEGER :: my_function

3.函數在被調用時,也必須在調用函數前面對其進行類型聲明,聲明方式如下:

TYPE :: function_name

4.使用函數計算兩個實數之和的例子:

PROGRAM test_func
IMPLICIT NONE
REAL :: func
REAL :: i = 2, j = 5
WRITE(,) func(i,j)
PAUSE
END PROGRAM test_func

REAL FUNCTION func(a,b)
IMPLICIT NONE
REAL, INTENT(IN) :: a, b
func = a + b
END FUNCTION func

5.函數的參數傳遞過程也是傳址傳遞。
6.過程名相當于也是個指針,包含子程序和函數。所以可以將過程作為參數傳遞給其他過程,類似C中的函數指針。
7.必須在被調用函數(或子程序)和主程序中使用EXTERNEL關鍵字來聲明的用戶自定義函數(或過程)才可以當作調用參數傳遞。EXTERNEL發生的使用方法與其他屬性一樣,但也有一個自己的專有格式,如下:

REAL, EXTERNEL :: func_1, func_2
!專有格式
EXTERNEL func_1, func_2

多維數組

1.二維數組的聲明方式舉例:

!聲明一個由3行6列構成的實數數組,總共有18個元素。第一個下標從13,第二個下標是16
REAL, DIMENSION(3,6) :: sum

!聲明一個101行21列的整數數組,總共2121個元素,第一個下標有效值是0100,第二個是020
INTEGER, DIMENSION(0:100, 0:20) :: hist

!聲明一個7行10列的數組,總共70個元素。數組的類型是字符型,每個數組元素包含6個字符。第一個下標從-3到3,第二個1到10
CHARACTER (len=6), DIMENSION(-3:3, 10) :: counts

2.Fortran中的數組存儲方式是列優先,與CUDA的網絡線程分配是類似的,而C/C++則是以行優先。也就是說Fortran中二給數組的內存在分配時是先為第一列分配內存,然后是第二列…
3.二維數組初始化方式:賦值語句、類型聲明語句或是Fortran的READ語句。
4.賦值語句初始化二維數組方式:

INTEGER, DIMENSION(4,3) :: istat
DO i=1,4
DO j=1,3
istat(i,j) = j
END DO
END DO
!等價于下面使用數組構造器生成賦值的數組
istat = RESHAPE((/1,1,1,1,2,2,2,2,3,3,3,3/), (/4,3/))

內置的RESHAPE函數的使用格式為output = RESHAPE(array1, array2),它會改變一個數組的結構。其中array1包含了要被改變結構的數據,array2是一個描述新結構的一維數組。array2中元素的個數是輸出數組的維數,其元素值是每個維度的寬度,且array1中元素個數必須與array2所描述的元素個數相同。
由于數組生成器只能產生一維數組,所以需要使用這種方式。上例中就是將一個一維數據,改變成一個4行3列的二維數組,注意數組存儲是列優先。

5.聲明時直接初始化數組時初始值必須按列序優先排列,即首先是第一列的4個元素,然后第二列。eg:

INTEGER, DIMENSION(4,3) :: istat(4,3) = RESHAPE((/1,1,1,1,2,2,2,2,3,3,3,3/), (/4,3/))

6.用READ語句初始化二維數組。如果在一條READ語句的參數列表中出現了沒有下標的數組名,那么程序將會按照數組元素在計算機內存中的邏輯順序為數組的所有元素賦值。eg:

!如果文件INITIAL.DAT中含有數據1 1 1 1 2 2 2 2 3 3 3 3
INTEGER, DIMENSION(4,3) :: istat
OPEN(7, FILE='INITIAL.DAT', STATUS='OLD',ACTION='READ')
READ(7,*) istat

!等價于使用嵌套的隱式DO循環實現的例子
!假設INITIAL.DAT中含有數據1 2 3 1 2 3 1 2 3 1 2 3
INTEGER :: i,j
INTEGER, DIMENSION(4,3) :: istat
OPEN(7, FILE='INITIAL.DAT', STATUS='OLD',ACTION='READ')
READ(7,*) ((istat(i,j), j=1,3), i=1,4)

7.二維數組也可以使用下標三元組或下標向量的方式使用部分數組元素。例如a(:,1)表示選用的是數組的第一列,a(1,:)選用數組的第一行,a(1:3, 1:3:5)選用數組的第一到第三行,和第一、三、五列。
8.Fortran最多可支持到7維數組。使用方式與二維一樣,分配方式是按列優先。
9.很多函數都支持對整個數組操作,即將一個數組名傳遞給函數時,相當于對數組中的每一個元素都執行該函數。
10.加掩碼的數組賦值:where結構使用方法如下:

[name:] WHERE (mask_expr1)
Array Assignment Statement(s) !Block 1
ELSEWHERE (mask_expr2) [name]
Array Assignment Statement(s) !Block 2
ELSEWHERE
Array Assignment Statement(s) !Block 3
END WHERE [name]

這里的每個mask_expr是一個邏輯數組,它和數組執行語句中處理的數組具有同樣的結構。該結構使得Block1中的操作或操作集用于mask_expr1為TRUE的所有數組元素上。當mask_expr1為FALSE而mask_expr2為TRUE時,Block2的操作將應用于所有數組元素上,同理操作Block3。Fortran90中不允許有ELSEWHERE子句。例如:

!對數組value中值大于0的元素求對數
WHERE(value > 0.)
logval = LOG(value)
ELSEWHERE
logval = -99999.
END WHERE

11.也可以使用單行WHERE語句:

WHERE (mask_expr) Array Assignment Statement

12.Fortran95/2003中FORALL的用法

!求nxm數組work中所有元素的倒數
FORALL(i=1:n, j=1:m, work(i,j)/=0.)
work(i,j) = 1./work(i,j)
END FORALL

FORALL語句中的每個索引都是通過下標三元組的形式的來指定的:subscript_1 : subscript_2 : stride
動態數組

1.動態數組需要在定義是使用ALLOCATABLE屬性來說明,然后使用ALLOCATE語句來實際分配內存,使用DEALLOCATE語句來釋放分配的內存。例如:

!聲明一個100x11的數組,其中第二維下標從0~10
REAL, ALLOCATABLE, DIMENSION(:, :) :: arr
ALLOCATE(arr(100,0:10), STAT=status)

其中STAT=子句是可選的,用于檢查返回值狀態,如果分配成功,狀態為0,如果失敗則返回一個基于編譯器的正數。
2.可以使用內置函數ALLOCATED()在使用前測試數據是否已經成功分配空間,在沒有分配空間之前,對其進行的任何操作都是非法的。用法:

REAL, ALLOCATABLE, DIMENSION(:) :: input_data
...
IF(ALLOCATED(input_data)) THEN
READ(8,) input_data
ELSE
WRITE(
,*) 'Warning:Array not allocated!'
END IF

3.DEALLOCATE用法:DEALLOCATE(list of arrays to deallocate, STAT=status),例如:

DEALLOCATE(arr1, STAT=status)

派生數據類型-結構體

1.Fortran中的派生數據類型相當于C/C++中的結構體變量,注意只是相當于,因為在其派生數據類型中,只能由基本的內置數據類型或者已定義的用戶定義數據類型,但不能包含有函數或子程序,只能用于存放數據。
派生數據類型使用關鍵字TYPE來定義,定義方式為:

TYPE [::] type_name
component definitions
...
END TYPE [type_name]

2.派生數據類型的類型成員通過百分號%來引用,其相當于C/C++中的間接引用運算符->,例如:

!定義派生數據類型person
TYPE :: person
CHARACTER(len=14) :: first_name
CHARACTER :: middle_initial
CHARACTER(len=14) :: last_name
INTEGER :: age
END TYPE person
!聲明類型為person的變量john
TYPE (person) :: john
!將john的age元素設置為28
John%age = 28

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 229,732評論 6 539
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 99,214評論 3 426
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 177,781評論 0 382
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 63,588評論 1 316
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 72,315評論 6 410
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 55,699評論 1 327
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,698評論 3 446
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,882評論 0 289
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 49,441評論 1 335
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 41,189評論 3 356
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 43,388評論 1 372
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,933評論 5 363
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,613評論 3 348
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 35,023評論 0 28
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 36,310評論 1 293
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 52,112評論 3 398
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 48,334評論 2 377

推薦閱讀更多精彩內容