私はFORTRANとよく仕事をしていますが、ソースコードを書くための適切な方法で正式な指示を受けたことはありません。私は現在、モジュールを使用してグローバル変数を格納していますが、サブルーチンや関数を格納するためにもモジュールを使用できることを理解しています。私が使用するコードは非常に大きく複雑であるため、多くのサブルーチンがあります。すべての関数とサブルーチンをモジュールに含める必要がありますか?もしそうなら、なぜですか?
4 に答える
一般的に、最初の質問に対する答えは「はい」です。2番目の質問に対する答えはすぐにわかります。最初に、これは一般的な質問に対する一般的な回答であり、SO Fortranの質問にぶら下がっている明るい火花は、モジュールが適用できない特別な状況を思い付く可能性があることに注意してください。この回答はモジュールの初心者を対象としていることを事前に反論します。あなたがもはや新参者でなくなったら、あなたはあなたの質問に対するあなた自身の答えを定式化することができます。
モジュールは、プログラムまたはプログラムのスイートを編成および構造化するための補助として、プログラマーにとって最も役立ちます。これらは、ユーザー定義の型とそれらの型を操作する関数/サブルーチンの定義をカプセル化するためのメカニズムを提供します。Fortran 90および95では、このカプセル化は、プログラムをパーツに分解する方法に関するプログラマーのアイデアに依存しているという意味で、ややアドホックでした。Fortran 2003にオブジェクト指向機能が導入されたことにより、各モジュールに属する要素を識別するためのさらに明確な「ルール」が追加されました。
たとえば、有理算術の型と手順のモジュールを考えることができます。優れたアイデアを実装するすべてのコードを1つのモジュールに保持することで、プログラムの他の部分(詳細を知る必要はありません)から実装を非表示にし、公開したい部分のみを公開できます(PRIVATE
およびPUBLIC
キーワードを参照してください) 。 。コードをモジュールに編成することの別の利点をすぐに確認できます。USE
メガソースファイルから別のメガソースファイルにコードを切り取って貼り付けるよりも、新しいプログラムで有理演算モジュールを使用する方がはるかに簡単です。有理演算を実行する場合は、ファイル全体に広がるコードではなく、1つのモジュールでコードを処理します。
モジュールを使用すると、名前の衝突を管理することもできます。たとえば、有理算術モジュールがと呼ばれるadd
演算を定義し、また、と呼ばれる演算を定義する多倍長整数算術モジュールがある場合がありますadd
。USE
プログラム(または別のモジュール)でこれらのモジュールの両方を実行しようとすると、コンパイラーは、モジュールを使用するスコープ内で同じ名前が2回定義されていることを警告します(エラーが発生する可能性があります)。アソシエートモジュールエンティティを使用する場合は、名前の変更を使用できます。句を使用しONLY
て、ユーザーが必要とするモジュールエンティティのみをインポートすることもできます。
モジュールUSE
は推移的であることに注意してください。AがBを使用し、BがCを使用する場合、AがCを使用することも宣言する必要はありません(ただし、エンティティの名前を変更したり、ONLY
句を指定したりした場合は、特定の推移的なものを確認する必要があります場合)。
一言で言えば、モジュールは、プログラムを管理可能なチャンクに分割することによってプログラムの複雑さに対処するための主要なFortranメカニズムです。この機能がコンパイラーによって実装されるFortran2008では、SUBMODULE
sも導入されます。これにより、この方法で複雑さを処理するためのさらに優れたサポートが約束されます。
モジュールは、言語標準では、コンパイル時に引数に対して型チェックを行うために、モジュールで定義されたプロシージャへの明示的なインターフェイスをコンパイラが生成することを要求しているという点でも役立ちます。これらのインターフェイス(実際には表示されない)は、モジュール内で定義されていない(またはCONTAIN
それらを使用するプログラムユニット内で編集されている)プロシージャが持つ暗黙のインターフェイスとは対照的に、明示的に呼び出されることに注意してください。もちろん、そのようなプロシージャの明示的なインターフェイスを作成することもできますが、ほとんどの場合、短期および長期の実行では、コンパイラにそれを実行させる方が簡単です。
@Telginがすでに述べたように、モジュールはインクリメンタルコンパイルにも役立ちます。
モジュールを使用する主な利点の1つは、コンパイラがモジュールからの関数またはサブルーチンのインターフェイスチェックを自動的に実行use
して、適切なパラメータタイプでルーチンを呼び出していることを確認することです。このトピックに関する良い記事は、Doctor Fortranが明示的になることです-もう一度!。この記事から:
明示的なインターフェースを提供する方法はいくつかあります。最も簡単で最良の方法は、プロシージャをモジュールに入れるか、呼び出し元のプログラムまたはプロシージャのCONTAINEDプロシージャにすることです。これには、情報を2回書き込む必要がないため、いずれかの場所で間違ってしまう可能性が高くなるという利点があります。モジュールプロシージャまたは含まれているプロシージャがある場合、そのインターフェイスは、モジュール内または親スコープ内の他のすべてに自動的に表示されます。名前がPRIVATEとして宣言されていない場合、インターフェイスは、モジュールプロシージャを含むモジュールを使用する場所でも使用できます。
関連するすべてのルーチンを同じモジュールに入れることをお勧めします。モジュールは、私にとって、他の言語のクラスと同等です。モジュールは、関連するデータとルーチン(そのデータを操作する場合があります)をグループ化する方法です。したがって、ルーチンが論理的にモジュールにグループ化されている場合、モジュールはコードをナビゲートしやすくし、関数とサブルーチンの呼び出しに型チェックを追加する方法を提供します。
モジュールは、他のいくつかの回答で既に説明されているように、明示的なインターフェイスを自動的に提供することにより、Fortran プログラムを支援します。これにより、コンパイラーはプロシージャー呼び出しとプロシージャー宣言の引数間の一貫性をチェックできるようになり、多くの間違いが検出されます。モジュールのこの利点を示す Stackoverflow の回答を次に示します: Computing the cross product of two vectors in Fortran 90 , FORTRAN関数とポインター配列の Fortran セグメンテーション違反
関連する関数、サブルーチン、および変数を独自のモジュールに移動すると、プログラムの保守性が向上します。後でその一部を更新する必要がある場合、数万 (または数百) 行のコードを含む 1 つのソース ファイルを掘り下げる必要はなく、関連するファイルを開くだけで済みます。
もちろん、エディターの検索機能を使用して関連するサブルーチンを見つけることができると考えているかもしれませんが、コードを放置してから数か月後には、おそらくすぐに名前を思い出すことができないことに気付くでしょう。サブルーチンの組み合わせ、またはそれらがどのように組み合わされるか。それらを適切にグループ化することは、そのために非常に役立ちます。
サブルーチンと関数をモジュールに移動すると、コンパイラがプログラム全体ではなく単一のモジュールのみを再構築する必要がある場合、コンパイル速度も向上します。