INTERFACE文
copyright

green dotINTERFACE文

INTERFACE文は、手続引用使用宣言、利用者定義演算子、利用者定義代入の 機能がある。

  INTERFACE [総称指定]
      :
  END INTERFACE

総称指定には、次の3つがある。

  1. 手続引用使用宣言
     内部サブルーチンの引数の名前や引用仕様(引数の型や属性)は、呼び出す プログラムが同じプログラム単位なので知っている。しかし、 外部サブルーチンの引用仕様等は、呼び出すプログラムがわからないので INTERFACE文で定義する必要がある。INTERFACE文で引用仕様を定義すると 次のようなことができる。
    [例1]
    配列を小さい順に整列する外部サブルーチンsortを作成する。 外部サブルーチンsortには、配列だけを引数に指定するので引数の 情報をINTERFACE文で定義している。
      PROGRAM main
         INTERFACE
            SUBROUTINE sort(a)
               INTEGER,DIMENSION(:),INTENT(INOUT) :: a
            END SUBROUTINE sort
         END INTERFACE
         INTEGER,DIMENSION(5) :: data
         data=(/10,13,3,55,78/)
         CALL sort(data)
         WRITE(*,*) data
      END PROGRAM main
      SUBROUTINE sort(a)
         INTEGER,DIMENSION(:),INTENT(INOUT) :: a
         INTEGER,DIMENSION(1) :: mm
         INTEGER :: i,w,m
         INTRINSIC SIZE,MINLOC
         DO i=1,SIZE(a)-1
            mm=MINLOC(a(i:)); m=mm(i)+i-1
            w=a(i); a(i)=a(m); a(m)=w
         END DO
      END SUBROUTINE sort
    
    [例2]
    次のようなINTERFACE文を指定すれば、CALL sub(y=10,x=abc) のような呼出し方法ができる。
      INTERFACE                       !手続引用使用宣言
         SUBROUTINE sub(x,y,z)
            INTEGER,INTENT(IN) :: x
            INTEGER,INTENT(IN),OPTIONAL :: y
            INTEGER,INTENT(OUT) :: z
         END SUBROUTINE sub
      END INTERFACE
    
    [例3]
    次の2つのサブルーチン(isub,asub)は、それぞれの名前で引用することも できるし、総称名subでも引用できる。次のような整数型の変数a,bと 実数の変数x,yに対して、総称名subでCALLできる。
      INTEGER :: a,b
      REAL :: x,y
      CALL sub(a,b)  !isubがCALLされる
      CALL sub(x,y)  !asubがCALLされる
      INTERFACE sub
         SUBROUTINE isub(x,y)
            INTEGER,INTENT(IN) :: x,y
         END SUBROUTINE isub
         SUBROUTINE asub(x,y)
            REAL,INTENT(IN) :: x,y
         END SUBROUTINE asub
      END INTERFACE sub
    
  2. 利用者定義演算子
     利用者定義演算子を作成して、演算子を拡張することができる。利用 者定義演算子は、INTERFACE文にOPERATORを指定する。
    [例]
    構造型で定義した2つの整数を加算する利用者定義演算子.ADD.を 作成する例である。
         goukei=a_ten .ADD. b_ten
    

    利用者定義演算子は、モジュールの中のINTERFACE文で定義する。 演算子.ADD.は、addstr関数で加算の関数を作成する。関数内では、 入力の引数aとbを明示的にINTENT(IN)を指定する必要がある。

      MODULE structure
         TYPE str
            INTEGER :: first,second
         END TYPE str     
         INTERFACE OPERATOR(.ADD.)        !利用者定義演算子の定義
            MODULE PROCEDURE addstr
         END INTERFACE
       CONTAINS
         FUNCTION addstr(a,b) RESULT(c)   !構造体の加算関数
            TYPE(str),INTENT(IN) :: a,b
            TYPE(str) :: c
            c%first =a%first +b%first
            c%second=a%second+b%second
         END FUNCTION addstr
      END MODULE structure 
      PROGRAM main                        !主プログラム
         USE structure                    !モジュールの使用宣言
         TYPE(str) :: a_ten,b_ten,goukei
         a_ten=str(10,20)
         b_ten=str(123,456)
         WRITE(*,*) a_ten
         goukei=a_ten .ADD. b_ten
         WRITE(*,*) goukei
      END PROGRAM main
    
  3. 利用者定義代入
    利用者定義代入を作成して、利用者が代入操作を定義することができる。 利用者定義代入は、INTERFACE文にASSIGNMENTを指定する。この場合は、 代入操作を行うサブルーチンを定義し、サブルーチンは2つの仮引数を もたなければならない。1つ目の引数はINTENT(OUT)または、 INTENT(INOUT)属性をもたなければならず、2つ目の引数はINTENT(IN)属性を もたなければならない。

    [例]
    配列で宣言された論理変数の値を文字列の配列に置き換える代入文を 定義する。論理変数の値が真の場合は、'1'を入れ、偽の場合は、 '0'を文字列に入れる。
    主プログラムのmoji=bitは、論理変数から文字変数への代入であるため 通常はエラーになる。この例の場合、利用者定義代入が定義されている ためサブルーチンbitcharが実行され、文字変数に変換される。 この例では110が出力される。

      MODULE bitc
         INTERFACE ASSIGNMENT(=)
            MODULE PROCEDURE bitchar
         END INTERFACE
        CONTAINS
         SUBROUTINE bitchar(c,b)
            CHARACTER (LEN=1),DIMENSION(:),INTENT(OUT) :: c
            LOGICAL,DIMENSION(:),INTENT(IN) :: b
            INTEGER :: i
            INTRINSIC SIZE
             DO i=1,SIZE(b)
               IF (b(i)) THEN
                  c(i)='1'
               ELSE
                  c(i)='0'
               END IF
            END DO
         END SUBROUTINE bitchar
      END MODULE bitc
      PROGRAM main
         USE bitc
         CHARACTER (LEN=1),DIMENSION(3) :: moji
         LOGICAL,DIMENSION(3) :: bit
         bit(1)=.TRUE. ; bit(2)=.TRUE.; bit(3)=.FALSE.
         moji=bit
         WRITE(*,*) moji
      END PROGRAM main
    
line-end