TOP

FORTRAN77入門

目次

はじめに

目次へ戻る

動作環境

目次へ戻る

対象者

目次へ戻る

FORTRANとは?

目次へ戻る

g77とは?

GNU ProjectのFortranコンパイラ。 ANSI FORTRAN 77を基にGNU機能拡張をしています。 Fortran 95のためにはg95があります。

目次へ戻る

最終目的

FORTRAN77を学習することで、現代言語との差異を理解します。またこの学習成果として2cバイナリクロックのFORTRAN77版を 作成します。

目次へ戻る

コメント

* lower-case letters ok.C FORTRAN66 comments can also be denoted by the letter C

コメントは*からはじまる。カラムが72を超えないようにする。アスキー文字'C'でもコメントが可能であるが、 FORTRAN66の時の下位互換である。

 

目次へ戻る

コーディング規約

なし。

目次へ戻る

基本構造

c 
c hello.f
c 
c
      INTEGER i
      write(*,*)'hello world'
      goto 1
1     write(*,*)'1 is label'
      end 

大文字小文字は、評価しません。コメントを4行書き、INTEGER型の変数iを指定、writeで標準出力goto 1でラベル1へ移動、 writeで'1 is label'を標準出力に表示します。最後にendでプログラムを終了します。注意すべきは、ステートメントのはじめ6文字分は空白にしなければならない事です。Fortranが作られた時代のプログラミングは、ディスプレイではなく紙での入出力が行われていたからです。

このようにレイアウトが決まっていることを固定形式という。JavaやCなどの現代高水準言語は自由形式という。以下のようにラベル・ContinuationMaker・文・カードナンバー用領域となるため、実際にソースコードが記述できる部分はStatement fieldの部分だけになる。

12345 6 7-72 73-80
Label field Continuation Maker field Statement field hold card sequence number

 

目次へ戻る

ハローワールド

c 
c hello.f
c 
      write(*,*)'hello world'
      end 
目次へ戻る

ルール

大文字のA-Z(the 26 upper-case letters)と0-9(the 10 digits)と特殊文字13個(+-*/ =().,':$)のみ利用可能 ブランクと空白は全てプログラムとして無視される。 カラム1-5はラベルフィールド カラム6はcontinuation makerフィールド カラム7-72はステートメントフィールド

$ cat rule.fcc 
crule.f
c
c234567     
      PROGRAM rule
      WRITE(UNIT=*, FMT=*)'aaaaaassssssddddddddddddddddddddddddffffffffffffffff'
      STOP
      END
$ g77 rule.f
rule.f: In program `rule':rule.f:6:         WRITE(UNIT=*, FMT=*)'aaaaaassssssddddddddddddddddddddddddfffffffff
                             1                                             
2Character constant at (1) has no closing apostrophe at (2)

カラム6にcontinuation makerのダラーマークを設定している。 JavaやBourneシェルの\マークと同様である。

c
c rule.f
c
c234567
      PROGRAM rule
      WRITE(UNIT=*, FMT=*)'aaaaaassssssddddddddddddddddddddddddfffffffff
     $fffffff'
      STOP
      END 
目次へ戻る

データ形式

  • INTEGER
  • REAL (floating-point representation)
  • DOUBLE PRECISION
  • COMPLEX
  • LOGICAL
  • CHARACTER サンプル
c
c hello.f
c
      INTEGER i
      INTEGER j
      REAL    price
      REAL    tax
      tax = 0.05
      write(*,*)'input i'
      read(*,*) i
      write(*,*)'input j'
      read(*,*) j
      price = (i + j) * (1 + tax)

      write(*,*)'price=',price,'\n'
      end 
サンプル
      PROGRAM lazy
      INTEGER Ival=100.11
      REAL Rval=100.01
      WRITE(UNIT=*, FMT=*)Ival
      WRITE(UNIT=*, FMT=*)Rval
      stop
      end

      PROGRAM lazy
      Ival=100.11
      Rval=100.01
      WRITE(UNIT=*, FMT=*)Ival
      WRITE(UNIT=*, FMT=*)Rval
      stop
      end 

変数名の始めにIをつける(Ival)とInteger型になるので、シンボルネームが必要なくなる。 実際はI-Nの一文字。Real型の場合は、A-HまたはO-Zを最初の一文字にするとREAL型になる。

CHARACTERのサンプル

      PROGRAM FLEX
        CHARACTER CODE*8
        CHARACTER CLASS*6
        CHARACTER TITLE*16
*
        CLASS = CODE('SECRET')
        TITLE = CODE('ORDER OF BATTLE')
        WRITE(UNIT=*, FMT=*) CLASS
        WRITE(UNIT=*, FMT=*) TITLE
      END
*
      CHARACTER*(*) FUNCTION CODE(WORD)
      CHARACTER WORD*(*)
      CHARACTER BUFFER*80
        DO 15, I=1, LEN(WORD)
          BUFFER(I:I) = CHAR(ICHAR(WORD(I:I)) + 1)
15      CONTINUE
        CODE = BUFFER
      END
 
目次へ戻る

演算子

Authmetic Excpressions

**でExponentiationが可能だが剰余は無い。
c
c     cal.f
c
      program cal
      implicit none
c
      integer a;
      a = (100 + 1 - 1) * 2 / 200
      a = (a + 9) ** 2
      write(*,*) 'answer=',a,'\n'
      stop
      end 

Relational Excpressions

.LT. Less Than .LE. Less than or Equal to .EQ. EQual to .NE. Not Equal to .GT. Grater Than .GE. Grater Than or Equal to

      PROGRAM EXIF1
        IF ('a' .EQ. 'b') THEN
          WRITE(UNIT=*, FMT=*) 'EQUAL'
        ELSE IF ('c' .NE. 'D') THEN
          WRITE(UNIT=*, FMT=*) 'NOT EQUAL'
        ELSE
          WRITE(UNIT=*, FMT=*) 'OTHER'
        END IF
      END
 

Logical Expressions

.NOT. .AND. .OR. .EQV. .NEQV.

     IF (LGE(CDATA, '4') .AND. LLE(CDATA, '7')) THEN
       CARY(2,J)='*'
       WRITE(UNIT=*,FMT=*) '*'
     ELSE
       CARY(2,J)=' '
       WRITE(UNIT=*,FMT=*) ' '
     END IF
 
目次へ戻る

配列(DIMENSIONAL)

*
* dimension.f
*
      PROGRAM DMSN
* ONE-DIMENSIONAL ARRAYS
* Fortran arrays are indexed from 1 and up.
        REAL ARY(10)
* arbitrary index range following syntax 
* like Language C that is indexed indexed from 0 through 19.
        REAL CARY(0:10)
* TWO-DIMENSIONAL ARRAYS
        REAL TARY(4,6)

* SET INITIAL DATA
       DO 20 J=1,3
         DO 10 I=1,6
           TARY(J,I)=I*J
10       CONTINUE
20     CONTINUE

      END
 
目次へ戻る

I/O

サンプル

c
c hello.f
c
      INTEGER i
      write(*,*)'input:'
      read(*,*) i
      write(*,*)'output=',i,'\n'
c
c     print instruction same write.
      print *,'output=',i,'\n'
      end
      
c
c print.f
c
c
      INTEGER i
      read(*,*) i
      print *, 'output=',i
      end


c hello.f
c
      open(unit=10,file='output')
      write(10,*)'aaaa'
      write(10,*)'bbbb'
      write(10,*)'cccc'
      close(10)
      end 
目次へ戻る

制御構造

分岐

IF ( condition ) THEN ELSE IF ( condition) THEN ELSE END IF

      PROGRAM EXIF1
        IF ('a' .EQ. 'b') THEN
          WRITE(UNIT=*, FMT=*) 'EQUAL'
        ELSE IF ('c' .NE. 'D') THEN
          WRITE(UNIT=*, FMT=*) 'NOT EQUAL'
        ELSE
          WRITE(UNIT=*, FMT=*) 'OTHER'
        END IF
      END


*
* if.f
*
      PROGRAM IF
      INTEGER IN1, IN2
      WRITE(UNIT=*,FMT=*)'Enter 2 number'
      READ(UNIT=*, FMT=*) IN1, IN2
      WRITE(UNIT=*,FMT=*)'ans=', AD(IN1,IN2)
      END

      REAL FUNCTION AD(A1,A2)
      IF (A1 .NE. 1) THEN
          WRITE(UNIT=*,FMT=*)'hoge'
      ELSE
          AD = A1 + A2
      END IF
      END


* TRIANG
*
      PROGRAM TRIANG
      WRITE(UNIT=*,FMT=*)'Enter lengths of three sides:'
      READ(UNIT=*,FMT=*) SIDEA, SIDEB, SIDEC
      WRITE(UNIT=*,FMT=*)'Area is ' ,AREA3(SIDEA,SIDEB,SIDEC)
      END

      FUNCTION AREA3(A, B, C)
* Computes the area of a triangle from lengths of sides
* If arguments are invalid issues error message and returns zero.
      REAL A, B, C
      S = (A + B + C)/2.0
      FACTOR = S * (S-A) * (S-B) * (S-C)
      IF(FACTOR .LE. 0.0) THEN
          STOP 'Impossible triangle'
      ELSE
          AREA3 = SQRT(FACTOR)
      END IF
      END 

反復

DO Loop

DO ラベル 変数=値,ループ回数 処理 ラベル CONTINUE

DOの後がラベル名になる。


*
* doloop.f
*
      PROGRAM DOLOOP
*      REAL AMOUNT
*      REAL PCRATE
*      INTEGER NYEARS
*      REAL RATE
      WRITE(UNIT=*, FMT=*)'Enter amount, % rate, years'
      READ(UNIT=*, FMT=*) AMOUNT, PCRATE, NYEARS
      RATE = PCRATE / 100.0
      REPAY = RATE * AMOUNT / (1.0 - (1.0 + RATE)**(-NYEARS))
      WRITE(UNIT=*, FMT=*)'Annual repayments are ', REPAY
      WRITE(UNIT=*, FMT=*)'End of Year Balance'
* like 'for (int iyear = 1; iyear NYSERS; IYEAR++)
      DO 15, IYEAR = 1,NYEARS
          AMOUNT = AMOUNT + (AMOUNT * RATE) - REPAY
          WRITE(UNIT=*, FMT=*) IYEAR, AMOUNT
15    CONTINUE
      END 

 

目次へ戻る

関数

FUNCTION 関数名(引数...) 処理 関数名を戻り値にする事 END

*
* TRIANG
*
      PROGRAM TRIANG
      WRITE(UNIT=*,FMT=*)'Enter lengths of three sides:'
      READ(UNIT=*,FMT=*) SIDEA, SIDEB, SIDEC
      WRITE(UNIT=*,FMT=*)'Area is ' ,AREA3(SIDEA,SIDEB,SIDEC)
      END

      FUNCTION AREA3(A, B, C)
* Computes the area of a triangle from lengths of sides
      S = (A + B + C)/2.0
      AREA3= SQRT(S * (S-A) * (S-B) * (S-C))
      END 

SUBROUTINE 関数名 処理 END

*
* return.f
*
      PROGRAM hoge
        CALL SUBT(A)
        WRITE(UNIT=*, FMT=*)'a=',A
        A=100
        WRITE(UNIT=*, FMT=*)'a=',A

        RCODE = FUNCB(ARG1)
        WRITE(UNIT=*, FMT=*)'ARG1=',ARG1
        WRITE(UNIT=*, FMT=*)'RCODE=',RCODE
        
      END
      SUBROUTINE SUBT(A)
      A = 10
      WRITE(UNIT=*, FMT=*)'a=',A
      END
      FUNCTION FUNCB(B)
      B = 20
      FUNCB = 50
      END  
目次へ戻る

フォーマット

目次へ戻る

API(Intrinsic Functions)

言語標準のライブラリは30個と非常に少ない。関数名だけ列挙する。

ABS ACOS AIMAG ANINT ATAN2 CHAR CMPLX CONJG COS DBLE DIM DPROD EXP ICHAR INDEX INT LEN LGE LGT LLE LLT LOG LOG10 MAX MIN MOD REAL SIGN SQRT TAN

目次へ戻る

その他

外部プログラムの呼び出し アセンブラを変更していますので、必要な方のみリンクを進んでください。

 

目次へ戻る

デバック

g77はコンパイル時に当然だがエラーを標準出力に吐き出すので問題なくデバックできるだろう。

目次へ戻る

最後に

FORTRANは世界初の高水準言語であるため非常にアセンブラに近いことが理解できた。高水準であるという上でアセンブラでのPUSH,POP,JUMPなどより、人間が思考しやすいように、IF,DO,GOTO,ROUTINEなどの自然言語が使われている事が改めて実感できた。また2004年6月現在の言語はライブラリを使う事でさらに上位の志向(デザインパターンなど)を考慮して実装できるが、C言語に比べてもさらに自分でライブラリを作成しなければならないことが理解できた。またg77コンパイラから実行ファイルを生成しているので、きわめて速度が早いことが確認できた。そして標準ライブラリ(Intrinstic Functions)の個数やコンパイラ言語としては、容易な文法習得からも、なぜ今日までこの言語が科学技術計算で利用されているかも理解できた。科学技術計算においては、FORTRAN言語はあくまでも目的解決のツールであり、言語の複雑さや問題を解決する方法の多様性は時として必要のないのだろう。FORTRANが作られた歴史的背景もあるが、C/C++などに対して極めてシンプルであり、量子コンピュータなどの新たなパラダイムシフトが生まれても生き残る言語のような気がする。

目次へ戻る

参考資料

ANSI FORTRAN 77

Professional Programmer's Guide to Fortran77

http://www.uopmu.ees.osakafu-u.ac.jp/~yabu/soft/

目次へ戻る


イバラキングへのリンク Get Firefox Valid XHTML 1.1 Apple Darwinへのリンク