3

古い Fortran 77 コードを C++ に変換しようとしていますが、ほとんどの変数は次のような共通ブロックで宣言されています。

COMMON/BLK1/Gw(200),Eta(4096),t(4096),Phi(200),w(200)
COMMON/BLK2/g,dw,Vel,M,dt,N,Ioutp1,Ioutp2
COMMON/BLK3/Hs,Std,E,Hs1,Tdt

私が理解しているように、共通ブロックは、プログラム全体のさまざまなサブルーチンで変数にアクセスできるようにするためだけに使用されます。したがって、C++ プログラムでは、(メインの外部で) 変数を使用して構造体を作成し、この方法で変数を構造体のメンバーとして呼び出すことができますか?

4

3 に答える 3

2

このページの COMMON に関する私の理解に基づいて、C++ に相当するものは、common.h以下を含む (インクルード ガード付き) という名前のファイルを作成することです。

 namespace BLK1
 {
      int const Gw = 200;
      int const Eta = 4096;
      int const t = 4096;
      int const Phi = 200;
      int const w = 200;
 }

 namespace BLK2
 {
      extern int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
 }

 namespace BLK3
 {
      extern int Hs, Std, E, Hs1, Tdt;
 }

また、プロジェクト内のちょうど 1 つの.cppファイルで、const 以外の定義を提供する必要がありますfoo.cpp

 #include "common.h"

 namespace BLK2
 {
      int g, dw, Vel, M, dt, N, Ioutp1, Ioutp2;
 }

 namespace BLK3
 {
      int Hs, Std, E, Hs1, Tdt;    // initialized to 0 by default
 }

とは異なるタイプを使用したい場合がありintますunsigned long。初期化された値は const であると想定しています。そうでない場合は、初期化子に変更int constextern intて削除します。初期化子は、ファイル内の定義に入る必要があり.cppます。

ヘッダーで非 const、非 extern 変数を宣言するという間違いを避けてください。これにより、ヘッダーが 2 つの異なるユニットに含まれている場合、未定義の動作が発生します。

これらの変数にアクセスするには、たとえば次のように記述BLK1::Etaします。

ご想像のとおり、名前空間の代わりに aを使用する方が整頓されていると考えられるかもしれませんが、ヘッダーでstruct宣言され、正確に 1 つのファイルで定義される構造体のインスタンスを作成する必要があります。C++11より前の場合、初期化子を提供するのは面倒です。extern.cpp

(もちろん、グローバルを使用しないようにコードをリファクタリングする方が良いでしょう。しかし、直接変換を行うための最初のパスとしては役立つかもしれません)。

于 2014-09-15T12:17:43.710 に答える
2

同じ名前の共通ブロックは、メモリ内で互いに重複しています。メモリのチャンクを割り当て、それにポインタを型キャストできます。別のオプションは、共用体で宣言することです。それが組合が発明された理由です。確かに、ユニオンが設定されたら、他のモジュールで extern を使用します。

以下を共通ヘッダーに入れ、そのインスタンスをモジュール 1 に入れます。extern を追加して、モジュール 2 で見られるようにします。

union blk1
{
    struct module_1_view
    {
        double gw(200);
        double eta(4096);
        double t(4096);
        double phi(200);
        double w(200);
    } 

    struct module_2_view
    {
        double parameters(8592);   // 200 + 4096 + 4096 + 200
        double w_status(200);
    } 
}

モジュール 1 が、ファイルから module_1_view の変数に double のセットをロードする役割を担っていると想像してください。これらのパラメーターが読み込まれて検証されると、モジュール 2 が呼び出され、モジュール 2 ビューからパラメーターにアクセスします。パラメータの成功または検証について何かを示す実際には 200 のインジケータである w_status を除いて、それらのほとんどすべてがパラメータ変数を介してアクセスされます。

重要な点は、モジュール 1 と 2 が同じメモリ チャンク (したがって共用体) にアクセスし、独自の変数名のセットを使用することです。

于 2015-02-17T02:01:20.110 に答える
-1

Fortran と直接話すことはできませんが、c/c++ のプログラム全体で変数にアクセスできるようにしたい場合は、extern が探しているキーワードです。

Extern は、データを共有する C スタイルの方法です。C++ は、多くのオブジェクトに密接に結合された変数は良いオブジェクト指向ではありません。

レガシ コードの上で C++ の処理を​​実行しようとしている場合、C++ クラスへのポインターが渡される静的メソッドがラッパーとして機能することがあります。その簡単な例を次に示します。

extern int _magicVariable;

static void call( void* klass )
{
  ((MyClass*)klass)->functionCall( _magicVariable );
}

MyClass 内で、フレンドとして void call( void* ) という名前を付ける必要があります。これで、レガシー コードはクラスへのポインターを使用して (void*) を呼び出し、_magicVariable を OO デザインに渡すことができます。そこから、c++ がその役割を果たします。

肝心なのは、タスクを達成する方法はたくさんあるということです。目的のコード構造に基づいて、理にかなっていることを試してみてください。

于 2014-09-15T11:35:01.830 に答える