# | Fortran | C |
1 | bool MxM(double** M1, double** M2, double** Mout, int n); | |
Cでは、使うサブルーチンの宣言をあらかじめ行う必要があります。 もしこのサブルーチンが、複数のファイル(cpp)で使用される場合は、この宣言をヘッダーファイルとして作成します。そして #include <xxxxx.h> を、各ファイルの先頭に記載すれば、書き間違いのリスクを減らすことができます | ||
2 | DIMENSION A(2,2), B(2,2), C(2,2) | int n=2; double **A; double **B; double **C; |
FortranではDimension をあらかじめ 2 と固定しています、Cでは Dimension であることのみを宣言して、大きさは指定していません。 Cでは、コンピュータのメモリを有効利用するために、Dimensionの大きさを可変に設定することができます。 そのため、プログラムの途中で、Dimensionの大きさが初めて決定するようなものでも、「とりあえず巨大にDimensionを取っておけば良いかな」ということで、使わないメモリ領域をあらかじめとっておく必要がなく、メモリが必要になったらその都度Dimensionの大きさを設定すればよいので、メモリ使用が経済的(ww)です | ||
3 | bool ret; | |
bool はbooleanで真(true)と偽(false)の2種類の値だけを扱います。 ここでは、MxMのサブルーチンの中で、Dimensionの大きさが0以下だった場合はfalseとしました。 | ||
4 | A = (double **)(malloc (sizeof(double*) * n)); for (int i = 0; i < n; i++) A[i] = (double )malloc(sizeof(double) * n); |
|
2では シンボルAがDimensionであることを宣言していますが、その大きさを設定しているのがこの行です。 なお、ここで使用しているmalloc()関数は、最初のinclude文、 #include <malloc> の中で宣言されています。 | ||
5 | A(1,1)=1; A(1,2)=2; A(2,1)=3; A(2,2)=4 |
A[0][0]=1; A[0][1]=2; A[1][0]=3; A[1][1]=4; |
ここではDimensionに値を入れていますが の行列の入力の方法に注意をする必要があります。 FORTRANでは2の大きさのDimensionでは、1から2の成分となりますが、Cでは2の大きさのDimensionでは0から1の成分となります。 これはグラフのX,Y軸の使い方と同じで、0 origin と考えるとわかりやすいです。 |
||
6 | DO l I=1,2 DO 2 J=1,2 C(I,J)=0.0; 2 CONTINUE 1 CONIINUE |
for (int j = 0; j < n; j++) { for (int i = 0; i < n; i++) { C[j][i] = 0.0; } } |
FORTRANでのDOループは、Cでのfor文となります。 DOループでは、どこまでループさせるかを行番号とCONTINUで表示していますが、Cではfor文の範囲を{ }カギかっこで指定します。 また、FORTRANでは、I=1,2ということで、I を1から2まで変位させていますが、for文では、 for (int j = 0; j < n; j++) integer宣言したj、初期値0を、jがnより小さい間だけ、jを1ずつ大きくしてゆく と、書きます。ここでnは、2なので、jは0,1 と変位することになります |
||
7 | CALL MXM(A, B, C, 2) | ret=MxM(A, B, C, n); |
FORTRANではサブルーチンを呼ぶときはCALL文を使用しますが、Cでは、そのままのfunctionとして使用します。 このfunctionは、1 で宣言されています |
||
8 | if (A) { for (int i = 0; i < n; i++) { if (A[i]) free(A[i]); } } free(A); |
|
Cでは、いつでも自由にDimensionの大きさを設定できることを4で記載しましたが、使わなくなったDimension:メモリ空間を解放する必要があります。 なおプログラムが終了すれば、すべてのメモリ空間は解放されます。 プログラムの途中で使用しなくなったメモリ空間を解放できるので、プログラムのほかのシンボルが空いたメモリ空間を使用できるようにできるため、経済的(?)です。 大きなDimensionを使うプログラムでブルースクリーンになったり、プログラムが吹っ飛ぶのは、大概メモリの使い過ぎなので、これを使用して、こまめにメモリを解放してあげると、プログラムの安定性がでてきます。 なお、ここで使用しているfree()関数は、最初のinclude文、 #include |
||
9 | // ------------SUB ROUTINE MXM ------- SUBROUTIN MXM(A,B,C,N) DIMENSION A(N,N), B(N,N), C(N,N) INTEGER I,J,K DOUBLE PRECISION S //A x B DO l I=1,N DO 2 J=1,N S=0.0 DO 6 K=1,N S=S+A(I,K) * B(K,J) 3 CONTINUE C(I,J)=S 2 CONTINUE 1 CONIINUE RETURN END |
//---------------------------------------- // Sub routine M x M //---------------------------------------- bool MxM(double** M1, double** M2, double** Mout, int n) { double s; if(n<1) return false; //M1 x M2 for (int i = 0; i < n; i++) { for (int j = 0; j < n; j++) { s=0.0; for (int k = 0; k < n; k++) { s=s + M1[i][k] * M2[k][j]; } Mout[i][j]=s; } } return true; } |
サブルーチンについては、行列をポインタとして渡す(C言語)か、シンボルとして渡す(FORTRAN)かの他には、すでに説明した通りです |
次のページ →
C言語での特徴
「有限要素法における平面トラスの解析」プログラムをC言語で書いてみる : 目次 |
0 件のコメント:
コメントを投稿