1.副プログラムの概念
2.関数副プログラム
関数副プログラムの例
関数副プログラムは関数(前回授業)で述べた外部関数を定義するプログラムである。プログラム例は 関数の3.外部関数を参照のこと。
FUNCTION文 関数副プログラムを記述する方法を厳密に述べる。 関数副プログラムはFUNCTION文によってその記述が開始され、END文によって終了する。この関数副プログラムの枠組みは、主プログラムの枠組みがPROGRAM文で始まり、END文で終了することに対応する。 FUNCTION文の一般形は次の通り。 |
FUNCTION func( d1, d2,...., dn ) |
funcは外部関数であり、それは英字名を用いて付けられる。外部関数名は主プログラムのPROGRAM文で指定されるプログラム名と同じであってはならない。diは引数えあり、変数名、配列名が用いられる。仮引数は主プログラムからデータを受け取る役目をするが、関数副プログラムの中で演算された値を仮引数に引き渡してもかまわない。仮引数の並びは、引数の順序、個数および型を示すことだけに意味があり、主プログラムの実引数の英字名とは一致しなくてもよい。 外部関数は型を持っており、その宣言は文関数と同様に、「暗黙の型宣言」、「IMPLICIT文による宣言」、「型宣言文による宣言」により行われる。したがって暗黙の型宣言に合致しない型の外部関数、例えば複素数の外部関数CMPは、その関数の型を FUNCTION CMP(X,Y,Z) COMPLEX CMP, X, Y, Z ・・・ と型宣言文(あるいはIMPLICIT文)によって宣言をする必要がある。この場合、FUNCTION文と型宣言文を一緒にして、 COMPLEX FUNCTION CMP(X,Y,Z) COMPLEX CMP, X, Y, Z ・・・ と、FUNCTION文の前に型を示すキーワードを付けても構わない。 FUNCTION文とEND文の間の部分には、外部関数の手続きを記述する。そこには主プログラムとほとんど同様な形式で、宣言文、文関数定義文、実行文などを記述することができる。実行文の中には、関数の結果を主プログラムに引き渡すために、結果を外部関数名にセットする代入文 FUNC = ・・・・ が1つ以上なければならない。また RETURN文も1つ以上記述されていなければならない。
外部関数の引用 外部関数の引用は、主プログラムの実行文の式の中に外部関数を記述することによって行われる。式の指定が許されている実行文ではどんな実行文でもよいが、一般には次のように、代入文の式の中に記述される。 |
v = ・・・func( a1, a2,・・・, an )・・・ |
funcは外部関数名であり、aiは引数である。実引数には定数、変数、配列、配列要素、文字部分列、式を用いる。実引数は外部関数が引用される時点で、値が定まっていなければならない。実引数と関数副プログラムの仮引数とは、その並びの個数、順序、型がそれぞれ対応しなければならない。実引数が英字名の場合には、それは仮引数の英字名と異なってもよい。実引数と仮引数の詳しい対応規則については、 4.引数の対応規則で述べる。
制御の流れとRETURN文 外部関数の引用は次の順序で実行される。 @ 実引数が式であれば、それが演算される。 A 実引数とそれに対応する仮引数が結合される。 B 関数副プログラム中の手続きが実行される。 C 外部関数名に結果が出力される。 関数副プログラムから主プログラムへの戻りは、 RETURN文によっておこなわれる。この文は関数副プログラム中に必ず1つ以上なければならない。 |
主プログラム PROGRAM MNTST
REAL MEAN DIMENSION N(100) I=1 10 READ(5,*,END=20) N(I) I=I+1 GO TO 10 20 A=MEAN(N,I+1) WRITE(6,*) 'AVERAGE=',A STOP END 副プログラム REAL FUNCTION MEAN(BF, N)INTEGER BF(100) TOTAL=0 DO 10 I=1,N TOTAL=TOTAL+BF(1) 10 COTINUE MEAN=TOTAL/N RETURN END |
例題 配列に保持されたデータを合計して平均値を求める関数副プログラムと、それを引用する主プログラムの例 |
主プログラムMNTSTの実引数は配列Nと式(I−1)である。関数副プログラムMEANの仮引数は配列BFと変数Nである。仮引数BFは実引数の整数型配列Nと対応しているので、BFには整数型配列の宣言がされている。仮引数Nは実引数の整数式と対応している。 |
3.サブルーチン副プログラム
サブルーチン副プログラムの例
関数副プログラムは複雑な関数を定義することはできるが、原則として1関数しか定義できず、関数副プログラムは単に文関数を発展させたものにすぎない。 副プログラムの考え方は関数に限らず、一般の手続きに対して適用してもかまわない。例えば、分類や検索などの手続きをひとまとめにして定義しても副プログラムの主旨( 1.副プログラムの概念-副プログラムの特徴参照)に合致するものである。しかし、これらの手続きに適合する副プログラムは、1つだけではなく複数の結果の出力を可能とする形式の副プログラムでなければならない。このような役割を果たす副プログラムが サブルーチン副プログラムである。まず、簡単な例を用いてサブルーチン副プログラムを説明する。今、A,B,Cをデータとして入力し、その3つを係数とする2次方程式 AX2+BX+C=0 の重根・実根を求める(ただし、虚根、重根、実根の区別もおこなう)プログラムを単一のプログラム(主プログラムだけ)の形式で記述すると、次の例題の左側のようになり、これを主プログラムとサブルーチン副プログラムに分割すると、右側のようになる。 |
PROGRAM SBTST1
READ(5,*) A, B, C D=B**2-4*A*C IF(D.LT.0) THEN IFLG=1 X1=0 X2=0 ELSE IF(D.EQ.0) THEN IFLG=2 X1= -B/(2*A) X2=0 ELSE IF(D.GT.0) THEN IFLG=3 X1=(-B-SQRT(D))/(2*A) X2=(-B+SQRT(D))/(2*A) END IF WRITE(6,*) 'FLAG',IFLG & ,'A=',A,' B=',B,' C=',C & ,' X1=',X1,' X2=',X2 STOP END |
主プログラム PROGRAM SBTST2 READ(5,*) A, B, C CALL ROOT(A,B,C,IFLG,X1,X2) WRITE(6,*) 'FLAG',IFLG & ,'A=',A,' B=',B,' C=',C & ,' X1=',X1,' X2=',X2 STOP END サブルーチン副プログラム SUBROUTINE ROOT(A,B,C,IFLG,X1,X2) D=B**2-4*A*C IF(D.LT.0) THEN IFLG=1 X1=0 X2=0 ELSE IF(D.EQ.0) THEN IFLG=2 X1= -B/(2*A) X2=0 ELSE IF(D.GT.0) THEN IFLG=3 X1=(-B-SQRT(D))/(2*A) X2=(-B+SQRT(D))/(2*A) END IF RETURN END |
例題 単一プログラム例(左)とサブルーチン副プログラムを用いた例(右)
図-2 主プログラムとサブルーチン副プログラムの枠組
CALL文
サブルーチンの引用は、主プログラムのCALL文によって行われる(図-2)。CALL文の一般形は次の通り。 |
CALL sub( a1, a2,・・・, an )・・・ |
subはサブルーチン名であり、aiは実引数である。実引数には定数、変数、配列、配列要素、文字部分列、式を用いる。実引数はサブルーチンが引用される時点で、値が定まっていないといけない。実引数とサブルーチン副プログラムの仮引数とは、その 並びの個数、順序、および型がそれぞれ対応している必要がある。実引数が英字名の場合には、それは仮引数の英字名と異なってもかまわない。実引数と仮引数の詳しい対応規則については4.引数の対応規則で述べる。
制御の流れとRETURN文 サブルーチンの引用は次の順序で実行される。 @ 実引数が式であれば、それが演算される。 A 実引数とそれに対応する仮引数が結合される。 B サブルーチン副プログラムの手続きが実行される。 C 実引数に結果がセットされる。 サブルーチン副プログラムから主プログラムへの戻りは RETURN文で行われ、主プログラム内のCALL文の次の実行文に戻る。REURN文はサブルーチン副プログラムに必ず1つ以上なければならない。また、必要があれば、サブルーチン副プログラム内にSTOP文を記述してもかまわない。 |
4.引数の対応規則
主プログラムが関数副プログラムあるいはサブルーチン副プログラムを引用すると、実引数と仮引数はそれぞれ並びの順序で結合され、データは引数を介して両プログラム間で受け渡される。この場合、実引数と仮引数は、次のような対応関係になければならない。 |
@ 実引数と仮引数は、個数、型、順序において、相互に対応していなければならない。 A 実引数となりえる要素は、定数、変数、配列、配列要素、文字部分列および式であり、仮引数となりえる要素は、変数と配列であるが、それらの英字名は両プログラム間で異なってもかまわない。 |
ここでは、これらの規則を例を用いて詳しく説明する。以下の説明にはサブルーチン副プログラムを用いているが、その内容は関数副プログラムにもあてはまる。 (1) 実引数と仮引数の個数は同じでなければならない。次に誤った例を示す。 |
主プログラム PROGRAM MAIN1| CALL SUB1 (A,B,C,D,E)| END 副プログラム SUBROUTINE SUB1(P,Q,R)| END |
誤例 引数の数が異なる
(2) 相互に対応する実引数と仮引数の型は同一でなければならない。次に誤った例を示す。 |
主プログラム PROGRAM MAIN2REAL A,B DOUBLE PRECISION C | CALL SUB2(A,B,C) | END 副プログラム SUBROUTINE SUB2(P,Q,R)REAL P,Q,R | END |
誤例 引数の型が異なる
(3) 実引数と仮引数の並びの順は一致してなければならない。次に誤った例を示す。 |
主プログラム PROGRAM MAIN3DIMENSION P(10) CHARACTER C*10, P*5 | CALL SUB3(N, P,C)| END 副プログラム SUBROUTINE SUB3(N,C,P)DIMENSION P(10) CHARACTER C*10, P*5 | END |
誤例 変数Cと配列Pの順序が異なる
(4) 実引数が変数、配列要素、文字部分列の時、それに対応する仮引数は変数でなければならない。この場合、仮引数を再定義してもよい。次に正例を示す。 |
主プログラム PROGRAM MAIN4DIMENSION A(10) CHARACTER C*5 | A(3)=1000. CALL SUB4(A(3),C(2:4),X) | END 副プログラム SUBROUTINE SUB4(P,CHR,Q)CHARACTER CHR*3 | Q=2000. END |
正例 仮引数を再定義した例
(5) 実引数は定数、関数引用(ただし文関数の引用は除外)は演算子を含む式またはカッコで囲まれた式であってもよいが、それに対応する仮引数は変数でなければならない。この場合、仮引数を再定義してはならない。引数を介したデータの受け渡しは主プログラムから副プログラムに対して行われるだけである。次に正例を示す。 |
主プログラム PROGRAM MAIN5| CALL SUB5(5.,SQRT(X),2.8+N,(X+Y)/Z) | END 副プログラム SUBROUTINE SUB5(A,B,C,D)| END |
正例 実引数が式またはカッコで囲まれた式の場合
(6) 実引数が配列のときには、仮引数も配列でなければならない。さらに対応する配列の型、次元、大きさは同じでなければならない。次に正例を示す。特に重要! |
主プログラム PROGRAM MAIN6DIMENSION A(10),B(100,20) | CALL SUB6(A,B,P,Q) | END 副プログラム SUBROUTINE SUB6(X,Y,P,Q)DIMENSION X(10),Y(100,200) | END |
正例 実引数が配列のとき
(7) 引数が文字型の場合、実引数の長さは仮引数のそれと等しいかそれよりも長くなければならない。実引数が文字部分列の場合には、文字部分列の長さが実引数の長さとなる。実引数が文字演算子を含んだ式であるならば、その結果が実引数の長さになる。次に誤例を示す。 |
主プログラム PROGRAM MAIN7CHARACTER C*10 | CALL SUB7('AB'//'XYZ',C( 2:6))| END 副プログラム SUBROUTINE SUB7(CHR1,CHR2)CHARACTER CHR1*4,CHR2* 10| END |
誤例 仮引数CHR2がそれに対応する実引数よりも長い
(8) 仮引数は、定数、式、配列要素、文字部分列であってはならない。次に誤例を示す。 |
主プログラム PROGRAM MAIN8DIMENSION E(10) CHARACTER C*10 | CALL SUB9(A,B,E(1),C) | END 副プログラム SUBROUTINE SUB8(20.,X+Y,P(1),C(2:5))DIMENSION P(10) CHARACTER C*5 | END |
誤例 仮引数が血数、式、配列要素、文字部分列
5.プログラムの構造と連結
質問・意見等
940-2188 |
新潟県長岡市上富岡町1603-1 長岡技術科学大学 環境・建設系 |
|
環境・建設計算機実習T 一部担当 |
|
犬飼 直之(内線 9624)inu@nagaokaut.ac.jp |
GLESCO
( GLobe, EStuary and COast )
Hydrauric Engineering Lab. Nagaoka University of Technology