6

Fortranでは、関数とサブルーチンの間に明確な違いがあります。関数は1つの値を返し、サブルーチンは値を返しません。これにより、2つの違いのカスケードが導入されます。1つの例は、呼び出しセマンティクスです。他の言語と同じように関数を呼び出すことができますが、サブルーチンを呼び出すには、call最初にステートメントを発行する必要があります。

Fortran95にポインタとデータ型が追加されたことで、サブプログラムを関数にしたり、サブルーチンをレガシー用に保持したりすることに技術的な制限はないようです。関数は、0(ダミーの整数を返すだけ)、1つ、または複数の値を返すことができます(たとえば、C ++ STLペアなどの型の割り当てられたインスタンスへのポインターを返すことができます)。

私が間違っている?サブルーチンにはある機能とない機能があるため、Fortranプログラミングにはまだサブルーチンが必要ですか?

4

5 に答える 5

17

comp.lang.fortran アーカイブを検索すると、関数のセマンティクスに関する議論が見つかります。IIRC では、副作用のある関数に対して許可されているものと許可されていないものが標準で明確に指定されていないことがわかりました。

たとえば、コンパイラは最適化できますか

x = foo(引数) + foo(引数)

の中へ

x = 2 * foo(引数)

または別の例として、

x = y + フー(y)

foo() が y の値を変更するとどうなるでしょうか? Fortran には C のシーケンス ポイントの概念がないことに注意してください。

一般に、複数の専門家による推​​奨は、関数が純粋な場合にのみ使用し、それ以外の場合はサブルーチンを使用することです。そして、それは私自身も従うべきアドバイスです。

于 2010-10-15T15:31:20.213 に答える
6

サブルーチンはどこにも行かないと思います。他のほとんどの言語では、値を返すメソッドと返さないメソッドを使用できます。ダメな理由が見当たりません。物事を変えるために誰も動かされるべきではありません。

レガシだけでも、サブルーチンは Fortran が存続する限り存続すると述べています。Fortran が存在する限り、アクションを実行して何も返さないメソッドを作成しても問題はありません。

アップデート:

なぜ「面倒くさい」と言うのですか?大したことは何ですか?私は、サブルーチンが適切な状況で使用されたときに「面倒」であるという考えには同意しません。

Fortran は、バージョン 77 以降、おそらくそれ以前から、関数とサブルーチンの区別を維持してきました。他の C ファミリー言語も同様です。なんでいきなりこんなに面倒くさいの?長い間ポインタとオブジェクトを持っていた言語でさえ、void を返すメソッドがあります。

于 2010-10-15T11:27:10.503 に答える
2

また C を fortran でプログラミングしようとしているのですね。;-)

私の意見では、そうです。理由が 1 つだけある場合は、関数よりも把握しやすく、理解しやすく、広く使用されています。

また、これは建設的な質問ではないと思うので、-1 です。それらが気に入らない場合は、使用しないでください。

于 2010-10-15T15:09:19.813 に答える
0

私の理解が正しければ、ステファノはサブルーチンのアイデアに反対していません。彼らに対する意見はナンセンスです。彼は、サブルーチン/関数に異なるスタイルを使用することに反対しました。

Fortran は命令型プログラミング言語です。より正確には手続き型プログラミング言語です (さらに正確には構造化プログラミング言語です)。

命令型プログラミングでは、状態とそれを変更するステートメントがあります。手続き型プログラミングでは、変更を行うためのツールは手続きです (手続き内の変更をローカライズします)。プロシージャは値を返す場合と返さない場合があります。そして、この事実 (プロシージャの戻り値であるかどうかにかかわらず) が、プログラミング言語に 2 つの異なるエンティティを持つ重要な理由だとは思いません。関数のみを (C のように) 持つことができ、実際に何かを返す必要がない場合 (void) に特別なものを返すだけです。または、Modula-2、Oberon などのように値を返すことを許可するプロシージャと特別な構文のみを持つことができます。

言語には、プロシージャーを宣言するためのスタイルが 1 つだけあるはずです。私はあなたに同意します、ステファノ。

于 2010-10-15T12:58:13.220 に答える
-3

私がこの質問に自分自身で答えなければならないという事実は正気ではありませんが、それがその方法です。

その違いは、Fortran では「他の言語のように関数を呼び出す」ことができないことに起因します。C では、値を代入せずに整数関数を呼び出すことができます。例

int foo() {
    return 5;
}
int main() {
    foo(); // this works
}

Fortran では、受け取る変数を常に関連付ける必要があります。例

module test
   implicit none

contains
   integer function foo()
      print *, "hello"
      foo = 0
   end function

end module

program hello
   use test
   integer :: x

   x = foo() ! this works
   foo() ! this does not compile

end program hello

つまり、ダミーの整数を返すことによって void 関数を「エミュレート」しても、レシーバー変数なしで呼び出すことはできません。

Fortran では、void戻り型は存在しません。技術的には、プログラムをすべての関数で構成し、callステートメントのすべての出現x =箇所を上記のように置き換えることができますが、いずれにせよ構文が C やその他の言語に似たものになることはありません。 void を返す関数。サブルーチンは「無効を返す」ことを許可する唯一のエンティティですが、呼び出しを実行するためのセマンティックは単に異なります。それを除けば、両者に違いはありません。

于 2010-10-15T14:48:54.597 に答える