- 締切済み
お願いします。
#include<stdio.h> #include<math.h> #define nmax 50 #define n 1000 #define nout 5 #define m 20 #define dfcoef 0.1 int main(void) { int i,j,k,r,dt,dx,it; double a[nmax][nmax*2], b[nmax][nmax],tb[nmax][nmax]; FILE *fq; fq=fopen("kadai4.csv","w"); for(i=0;i<m-1;i++){ //初期値を設定 a[i][m-1]=1.0; } for(it=0;it<=n;it++){ //時間増分するループ dt=1./(double)n; dx=1./(double)m; r=dt/(dx*dx); for(i=0;i<m-1;i++){ //係数行列の設定 a[i][i]=1+2*r; } for(i=0;i<m-2;i++){ a[i][i+1]=-r; } for(i=0;i<m-2;i++){ a[i+1][i]=-r; } for(i=0;i<m-3;i++){ for(j=i+2;j<m-1;i++){ a[i][j]=0.0; } } for(i=0;i<m-3;i++){ for(j=i+2;j<m-1;i++){ a[j][i]=0.0; } } hakidashi(m, a, b); //関数の呼び出し tb[0][0]=0.0; //tbを設定 tb[m][0]=0.0; for(i=0;i<m-1;i++){ tb[i+1][0]=b[i][0]; } for(i=0;i<m+1;i++){ fprintf(fq,"%f\t",tb[i][0]); } fprintf(fq,"\n"); for(i=0;i<m-1;i++){ //時間を進める a[i][m-1]=tb[i+1][0]; } } fclose(fq); return(0); } int hakidashi(double a[][nmax*2],double b[][nmax]) { int i, j, k, ip, jp; double coe, temp; for(ip=0;ip<m-1;ip++){ jp=0; coe=a[ip][jp]; for(j=1;j<m-1;j++){ //枢軸を設定 if(fabs(coe)<fabs(a[ip][j])){ coe=a[ip][j]; jp=j; } } for(j=0;j<m;j++){ //各列を枢軸で割る a[ip][j]=a[ip][j]/coe; } for(i=0;i<m-1;i++){ coe=a[i][jp]; for(j=0;j<m;j++){ //枢軸以外の各列の要素を0にする if(i==ip)continue; a[i][j]=a[i][j]-a[ip][j]*coe; } } } for(j=0;j<m-1;j++){ //単位行列にする for(i=0;i<m-1;i++){ if(a[i][j]==1.0){ for(k=0;k<m;k++){ temp=a[j][k]; a[j][k]=a[i][k]; a[i][k]=temp; } } } } for(i=0;i<m-1;i++){ //解行列を作成 b[i][0]=a[i][m-1]; } } このプログラムを実行するとプログラムを終了しますとでるのですがなぜなのか教えてください。
- みんなの回答 (5)
- 専門家の回答
みんなの回答
- tatsu99
- ベストアンサー率52% (391/751)
#2です。 >#define m 20 >でmの値はいれてあると思うのですが。 大変失礼しました。 以下の行を修正してください。 1.dt,dx,rをdouble型にする。 2.35行~44行付近の修正(2カ所) for(i=0;i<m-3;i++){ for(j=i+2;j<m-1;j++){ //ここを変更(i++をj++にする) a[i][j]=0.0; } } for(i=0;i<m-3;i++){ for(j=i+2;j<m-1;j++){ //ここを変更(i++をj++にする) a[j][i]=0.0; } } 3.47行目近辺の hakidashi(a, b); //関数の呼び出し //ここを変更(mをとる) 以上です。
- pyonmae
- ベストアンサー率64% (40/62)
こんにちは。 for(it=0;it<=n;it++){ //時間増分するループ dt=1./(double)n; dx=1./(double)m; ← (1) r=dt/(dx*dx); ← (2) 上記(1)の行にて、dxが1/20になるかと思いきや、整数なので切り捨てで0になります。 そのまま(2)に突入すると、0での除算で止まるという事になるかと思われます。
補足
回答ありがとうございます。 double dt,dx,r; と書き直して0にならないようにしたのですがやはりプログラムを停止しますとでてしまいます。
- sonata1229
- ベストアンサー率36% (76/206)
No1です。追記。 =プロトタイプ宣言= int hakidashi(double a[][nmax*2],double b[][nmax]); int main(void) { 定義 } int hakidashi(double a[][nmax*2],double b[][nmax]) { hakidashi関数定義 } あと、注意点ですが、 kadai4.csvは実行ファイルと同階層に存在していないと 強制終了しますよ。 fq=fopen(省略) ここで、ファイルがなかったら落ちます。 エラーチェックするべきです。 fq=fopen(省略) if (fq == NULL) { fclose(fq) return 1; }
お礼
回答ありがとうございます。
補足
同階層にあるはずなんですが実行するとkadai.exeは動作を終了しましたとでてしまいます。
- tatsu99
- ベストアンサー率52% (391/751)
for(it=0;it<=n;it++){ //時間増分するループ dt=1./(double)n; dx=1./(double)m; r=dt/(dx*dx); のr=dt/(dx*dx);を実行したとき、 dxの値は何も設定されていないので「不定」になります。 実行したOS、コンパイラが不明なので、それ以上は言及できませんが linuxの環境(gccでコンパイル)行った場合は、dxの値は0になります。 従って0でわり算を行っています。 0でわり算を行った場合は、プログラムの異常事態ですので、プログラムが異常終了します。(絶対に0で割ってはいけません)
お礼
回答ありがとうございます。
補足
#define m 20 でmの値はいれてあると思うのですが。
- sonata1229
- ベストアンサー率36% (76/206)
main関数でhakidashi関数を呼び出していますが、 hakidashi関数のプロトタイプ宣言がありません。 プロトタイプ宣言をしないのであれば、 hakidashi関数の定義を、Main関数より前に記述しないといけません。 プログラムは上から順番に実行されるので、 現状のコードで、hakidashi関数を呼び出しても、その時点でhakidashiは 定義されていません。 そのためのプロトタイプ宣言です。 また、hakidashi関数の引数は2つなのに、呼び出しでは引数3つ 指定していますが??
お礼
うまく実行することができました。 ありがとうございます。