(前頁)<<      >>(次頁)          (Up)

2章 準備勉強
2.1 FORTRANプログラムとC#プログラムの相違 (その1)



 FORTRANのプログラムと C#のプログラムを対比させながら、C#でプログラムを作成する時のコツ等を説明します。
 まず、非常に簡単なFORTRANサンプルを下記に示します。

===説明用FORTRANプログラム=== 
c 説明用FORTRANプログラム(動作確認はしていません)
      PROGRAM  TEST
      COMMON  /COMMONDATA/X
      REAL(8) X
     
      CALL SUB01(1.0)
      CALL SUB02(10)
      CALL SUB03
      STOP
      END
c サブルーチンその1
SUBROUTINE SUB01(DX)
      REAL(8) DX
      COMMON  /COMMONDATA/X
      REAL(8) X
     
      X=DX
      RETURN
END
c サブルーチンその2
SUBROUTINE SUB02(LOOPNUM)
      INTEGER LOOPNUM
      COMMON  /COMMONDATA/X
      REAL(8) X
      INTEGER LCNT
     
      DO 10 LCNT=0,LOOPNUM
      X = X + 1.0
   10 CONTINUE
      RETURN
END
c サブルーチンその3
SUBROUTINE SUB03
      COMMON  /COMMONDATA/X
      REAL(8) X
     
      WRITE(1,110) X
  110 FORMAT(F12.3)
      RETURN
END

    Sample.for

 動作としては、COMMON領域に定義されたXという変数に 
@SUB01で初期値を与える。
ASUB02で引数であたえた回数分 1.0を加算する。
BSUB03で表示する。
 という非常に簡単なものです。


 これと同じ内容をC#でプログラムしてみます。 プログラムの開発には Microsoft Visual C# Express Edition を使用します。
 Microsoft Visual C# の「ファイル」−「新しいプロジェクト」を選択し 表示されたダイアローグから 「コンソールアプリケーション」を選択します。

       
 
 すると 以下に示すように 「Program.css」というプログラムの型紙が自動的に生成されます。

    

ここで、

        static void Main(string[] args)
        {
        }

が、FORTRAN のメインプログラム 

    PROGRAM  TEST
       END

に相当します。Mainは予約語であり、勝手に使用することはできません。また、プログラムは必ずこの関数から動作を開始します。
 namespace, class については 後ほど説明することとします。

 説明用のFORTRAN プログラムには、メインの他に、サブルーチンがありました。そこで 同様にサブルーチンを追加します。

// 処理は追加していません。 メイン、サブルーチンの形だけを作成します。 
namespace TEST
{
    class Program
    {
        static void Main(string[] args)
        {
        }

        static void Sub01(double dX)
        {
        }

        static void Sub02(long LoopNum)
        {
        }

        static void Sub03()
        {
        }
    }
}


C#では "{" から "}" までが 処理の一纏まりになります。 また、void は 関数に戻り値が無い事を示します。 (static については 後ほど説明します。)

変数の型式は
   double   ←→ Real(8)
   long      ←→ INTEGER
と対応します。

 ところで、FORTRANプログラムでは、COMMON文を宣言し、変数Xを 全プログラムで共有していました。
 そこで、共有する変数Xを宣言します。

    class Program
    {
        static double X;
        static void Main(string[] args)
        {
         ...........

ここで、サブルーチンの中身を完成させます。


namespace TEST
{
    class Program
    {
        static double X;
        static void Main(string[] args)
        {
            Sub01(1.0);
            Sub02(10);
            Sub03();
        }

        static void Sub01(double dX)
        {
            X = dX;
        }

        static void Sub02(long LoopNum)
        {
            long lCnt;
            for (lCnt = 0; lCnt < LoopNum; lCnt = lCnt + 1)
            {
                X = X + 1.0;
            }
        }

        static void Sub03()
        {
            Console.WriteLine(X);
        }
    }
}

    プロジェクト: CSSTest01.lzh (解凍したファイルのTEST01.sln を Microsoft Visual C# 2008 から開いて下さい。2008以降のバージョンで開いた時には、バージョンアップの問い合わせがあるので、YESとして開いて下さい。 )

 FORTRANの
     DO  10  LCNT=0,LOOPNUM
    10 CONTINUE

 
の部分は C#では

    for( lCnt=0; lCnt < LoopNum; lCnt=lCnt+1 )
    {
    }


 と記述します。


 プログラムが完成すると、下図のように 「ディバッグ」−「ディバッグ開始」を選択してディバッグモードでプログラムを動作させます。
 この時、ブレークポイントを設定(止めたいところにカーソルを移動し、「ディバッグ」−「ブレークポイントの設定」を選択) しておくと、その場所でプログラムの実行を止めて、変数の中身を調べることができます。


         


 ところで、サンプルのFORTRAN プログラムでは、変数Xに COMMONDATA という名称がついていました。
 そこで、本C#プログラムでも CommonData という名前で、変数Xを区別してみます。

    class CommonData
    {
        public double X;
    }


 データの一纏まりを宣言するために C#では 「クラス: class」を使用します。
 つまり、
  class CommonData
  {
  }

内に 変数 Xを定義することで 「変数 X が CommonDataという器の中に入っている」ことを示すようになります。
 
ここで、示したCommonData内には 複数のデータを入れることが可能です。

   class CommonData
    {
        public double X;
        public double Y;
        public long N;
    }

 
上記の例では、 CommonDataという器の中に 変数 X、Y 及び N が入っています。(この変数X,Y,NをクラスCommonDataのメンバー変数と呼びます)

 ここから、少し話が難しくなりますが、FORTRANプログラムが動作するとき、メモリー内に変数が確保される様子を想像してみて下さい。
 FORTRANプログラムでは 使用する変数を格納するメモリー領域は プログラム実行時にすべて確保されます。    

    

 一方、C#においては class 宣言しても プログラム実行時には メモリー領域に変数を格納する領域は確保されません。
 メモリーを確保するためには new クラス名; として 明示的に宣言する必要があります。  

    


 また、確保された領域にアクセスするためには


    class CommonData
    {
        public double X;
        public double Y;
        public long N;
    }
    .....
    .....
    CommonData CmnDt = new CommonData();

    CmnDt.X = 10.0;
    CmnDt.Y = 12.3;
    CmnDt.N = 3;

の様に (メモリー領域名).(変数名) と記述します。


 先に作成したプログラムに対して、クラスCommonDataを利用するように改造したものを下記に示します。


namespace TEST
{
    class CommonData
    {
        public double X;
    }

    class Program
    {
        static CommonData CmnDt = new CommonData();

    // プログラムは このMain() から開始します。
        static void Main(string[] args)
        {
            Sub01(1.0);
            Sub02(10);
            Sub03();
        }

        static void Sub01(double dX)
        {
            CmnDt.X = dX;
        }

        static void Sub02(long LoopNum)
        {
            long lCnt;
            for (lCnt = 0; lCnt < LoopNum; lCnt = lCnt + 1)
            {
                CmnDt.X = CmnDt.X + 1.0;
            }
        }

        static void Sub03()
        {
            Console.WriteLine(CmnDt.X);
        }
    }
}

     プロジェクト: CSSTest02.lzh



  ここで、態々 データの纏まり「class CommonData」 にこだわったのは 理由があります。
  オブジェクト指向の考え方では 意味のある情報を 一つに纏めて扱うからです。
 次節からは、ここで作成したプログラムを発展させてオブジェクト指向プログラムにしていきます。


(前頁)<<      >>(次頁)

初版:2013/06/12 |