• 締切済み

お願いします。

#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]; } } このプログラムを実行するとプログラムを終了しますとでるのですがなぜなのか教えてください。

みんなの回答

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.5

#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をとる) 以上です。

ronald7777
質問者

お礼

うまく実行することができました。 ありがとうございます。

  • pyonmae
  • ベストアンサー率64% (40/62)
回答No.4

こんにちは。 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での除算で止まるという事になるかと思われます。

ronald7777
質問者

補足

回答ありがとうございます。 double dt,dx,r; と書き直して0にならないようにしたのですがやはりプログラムを停止しますとでてしまいます。

回答No.3

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; }

ronald7777
質問者

お礼

回答ありがとうございます。

ronald7777
質問者

補足

同階層にあるはずなんですが実行するとkadai.exeは動作を終了しましたとでてしまいます。

  • tatsu99
  • ベストアンサー率52% (391/751)
回答No.2

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で割ってはいけません)

ronald7777
質問者

お礼

回答ありがとうございます。

ronald7777
質問者

補足

#define m 20 でmの値はいれてあると思うのですが。

回答No.1

main関数でhakidashi関数を呼び出していますが、 hakidashi関数のプロトタイプ宣言がありません。 プロトタイプ宣言をしないのであれば、 hakidashi関数の定義を、Main関数より前に記述しないといけません。 プログラムは上から順番に実行されるので、 現状のコードで、hakidashi関数を呼び出しても、その時点でhakidashiは 定義されていません。 そのためのプロトタイプ宣言です。 また、hakidashi関数の引数は2つなのに、呼び出しでは引数3つ 指定していますが??

関連するQ&A

  • C言語 多重配列に関して

    以下のプログラムについての質問です。 10行目 for i = 0 の時、13行目 for j = 0 で scanf("%lf", &a[0][0])に10と代入します。 この時のドス画面は input 1-th line element:10 です。ここまではいいのですが、この次がよくわかりません。私の考えでは、10行目 i = 0 の時 13行目 j = 1 となって j がNMAXまでやったら、10行目のiが1になってまた同じように動いて、10行目の i がNMAXになったら、for文が終わると考えたのですが、このプログラムの実行結果(一番下にあります)を見てみると自分の考えが間違っていることに気がつきました。 3行3列のプログラムなので、a[0][0] a[0][1] a[0][2] a[1][0].......となると考え、scanfでドス画面に9回数字を打ち込むかと思ったのですが実際は3回でした。このプログラムはどのように読んだら良いのでしょうか?? 回答宜しくお願い致します。 1  #include <stdio.h> 2  #define NMAX 3 3 4  main() 5  { 6   double a[NMAX] [NMAX], b[NMAX] [NMAX], c[NMAX] [NMAX]; 7   int i,j,k; 8 9   printf("matrix 1:\n"); 10   for(i=0; i< NMAX; i++) 11   { 12   printf("input %d-th line element:", i+1); 13   for(j=0; j< NMAX; j++); 14   { 15   scanf("%lf", &a[i][j]); 16   } 17   } 18   printf("matrix 2:\n"); 19   for(i=0; i<NMAX; i++) 20   { 21   printf("input %d-th line element:", i+1); 22   for(j=0; j< NMAX; j++); 23   { 24   scanf("%lf", &b[i] [j]); 25   } 26   } 27  for(i=0; i<NMAX; i++) 28   { 29   for(j=0; j<NMAX; j++) 30   { 31   c[i][j] = 0; 32   for(k=0; k <NMAX; k++) 33   { 34   c[i][j] += a[i][k] * b[k][j]; 35   } 36   } 37   } 38 39  printf("matrix 1 * matrix2 = :\n"); 40  for(i=0; i<NMAX; i++) 41   { 42   printf("["); 43   for(j=0;j<NMAX; j++) 44   { 45   printf("%f", c[i][j]); 46   } 47   printf("]\n"); 48   } 49  }

  • 行列の行の入換え

    | -1 -1 -2 -1 10 | | -1 -2 -1 10 -1 | | -2 -1 10 -1 -1 | | -1 10 -1 -1 -2 | | 10 -1 -1 -2 -1 | この行列を次の順序で並び替えたいのですが 1.第1列にある要素の中で絶対値の最大値がある行を探し,その行と第1行を入れ換える. 2.第2列にある要素の中で絶対値の最大値がある行を第2行以下から探し,その行と第2行を入れ換える. 3.これを左上から右下へ順次移動して,行の入れ換えを行う. #include<stdio.h> #include<math.h> #define N 5 #define M 5 int main(){ float a[N][M]={{-1.0,-1.0,-2.0,-1.0,10.0},{-1.0,-2.0,-1.0,10.0,-1.0},{-2.0,-1.0,10.0,-1.0,-1.0}, {-1.0,10.0,-1.0,-1.0,-2.0},{10.0,-1.0,-1.0,-2.0,-1.0}}; float nmax; int i,j,k=0,s,imax; for(j=0; j<M; j++){ nmax = a[0][j]; imax = 0; for(i=1; i<N; i++){ if(fabs(nmax) < fabs(a[i][j])){ nmax = a[i][j]; imax = i; } } for(j=0; j<M; j++){ s=a[k][j]; a[k][j]=a[imax][j]; a[imax][j]=s; } k++; } for(i=0; i<N; i++){ for(j=0; j<M; j++){ printf("%5.1f ",a[i][j]); } printf("\n"); } return(0); } このように作成したのですが、1行目と5行目しかいれかわりません。 なぜでしょうか??

  • 行列に関して。

    以下の行列を対角成分が最も大きくなるような プログラムをつくりたいのですが 0   1   4  3 7   0   1  -5 1    3   0   7 -2   4   4  -8 #include<stdio.h> #include<math.h> #include<stdlib.h> #define NUM 4 int main(){ /* 初期化 */ int i; /* ループ変数 (行)*/ int j; /* ループ変数 (列)*/ int k; /* ループ変数 */ int imax; /* 最大値のi成分 */ int jmax; /* 最大値のj成分 */ double nmax; /* 最大値を入れるための変数 */ double tmp; /* ソートのための一時的な変数 */ double eps = 1.0e-6; /* 判定値 */ double a[NUM][NUM] = { { 0.0, 1.0, 4.0, 3.0}, { 7.0, 0.0, 1.0, -5.0}, { 1.0, 3.0, 0.0, 7.0}, {-2.0, 4.0, 4.0, -8.0}}; /* 対象とする要素位置 = k */ for( k = 0 ; k < NUM ; k++ ){ /*対象とする要素位置 = k*/ nmax = 0.0;/* 初期化 */ imax = k;/* 初期化 0とは限らない */ jmax = k;/* 初期化 0とは限らない */ /* 1.絶対値の最大値を求める */ for( i = k ; i < NUM ; i++ ){ for( j = k ; j < NUM ; j++ ){ if(fabs(nmax) < fabs(a[i][j])){ nmax = a[i][j]; imax = i; jmax = j; /* 対象としている行列要素の中で,最大となる行列要素のi,j成分を探す */ /*ここに絶対値の最大値を求め、nmax、imax、jmaxに代入するプログラムを書く*/ /*絶対値の求め方、数学関数fabs(x)を用いる*/ } } } /* 2.行入れ換え */ if( k != imax ){/* 対象としている行と最大値を持つ行が同じなら,入れ替える必要が無い */ for( j = 0 ; j < NUM ; j++ ){ tmp=a[k][j]; a[k][j]=a[imax][j]; a[imax][j]=tmp;/* 対象としている行と最大値を持つ行との入れ替え */ /*ここに行の入れ替え行うプログラムを書く*/ } } /* 3.列入れ換え */ if( k != jmax ){/* 対象としている列と最大値を持つ列が同じなら,入れ替える必要が無い */ for( i = 0 ; i < NUM ; i++ ){ tmp=a[i][k]; a[i][k]=a[i][imax]; a[i][imax]=tmp;/*対象としている列と最大値を持つ列との入れ替え*/ /*ここに列の入れ替え行うプログラムを書く*/ } } } /* 結果の出力 */ for(i=0; i<NUM; i++){ for(j=0; j<NUM; j++){ printf("%5.1f ",a[i][j]); } printf("\n"); } /*ここに行列の表示プログラムを書く*/ return(0); } 上のぷろぐらむを実行しても、1個目のfor文の1ループ目で終了してしまい 1行目と、4行目を交換、4列目と1列目を交換した行列だけが表示されます。 結果が以下のような行列にするにはどう改善すればよいでしょうか? -8.0   -2.0  4.0  4.0 -5.0   7.0  1.0  0.0   3.0   0.0  4.0  1.0  7.0   1.0  0.0  3.0 です。

  • セグメントエラー

    #include <stdio.h> #define S 10.0 #define L 10.0 void solve(int m,double a[][10],double f[]); main() { double t,me[10][10],fe[10]; int i,x; t=(S*L)/420; me[0][0]=t*156;me[0][1]=t*22*L;me[0][2]=t*54;me[0][3]=t*(-13)*L; me[1][0]=me[0][1];me[1][1]=t*4*L*L;me[1][2]=t*13*L;me[1][3]=t*(-3)*L*L; me[2][0]=me[0][2];me[2][1]-me[1][2];me[2][2]=t*156;me[2][3]=t*(-22)*L; me[3][0]=me[0][3];me[3][1]=me[1][3];me[2][3]=me[3][2];me[3][3]=t*4*L*L; for(i=0;i<4;i++){ fe[i]=1.0; } x=4; solve(x,me,fe); } void solve(int m,double a[][10],double f[]) { /* m=number of unknowns */ int i,j,k; double aa; /* forward elimination */ for(i=0;i<m-1;i++){ for(j=i+1;j<m;j++){ aa=a[j][i]/a[i][i]; f[j]-=aa*f[i]; for(k=i+1;k<m;j++){ a[j][k]-=aa*a[i][k]; } } } /* backward substitution */ f[m-1]/=a[m-1][m-1]; for(i=m-2;i>=0;i--){ for(j=i+1;j<m;j++){ f[i]-=a[i][j]*f[j]; } f[i]/=a[i][i]; } } 以上のようなプログラムについて、コンパイルはできるのですが、実行時に「セグメントエラー」と出てしまいます。たぶん配列の引渡しに原因があるようなのですが、どなたか詳しい原因(対処法)をご教授願いたいと思います。

  • すいません。。改めて質問!!

    #include<stdio.h> #define NMAX 200 int n; int a[NMAX], x[NMAX]; void yomikomi() { for(n=0; scanf("%d%d",&a[n],&x[n])!=EOF;n++); return; } void hyouzi() { int i; for(i=0;i<n;i++) printf("%5d %5d\n",a[i],x[I]); return; } void seiretu() { int i,j,max,k,w; for(i=0;i<n-1;i++){ max=x[i];k=i; for(j=i+1;j<n;j++) if(x[j]>max){ max=x[j];k=j; } w=a[k];a=[k]=a[i];a[i]=w; x[k]=x[i]; x[i]=max; } return; } main() { printf("sorting\n"); yomikomi(); printf(\nInput data\n"); hyouzi(); seiretu(); printf(\nSorted data\n); hyouzi(); return(0); } これを改良して偶数と奇数に分けてソートするプログラムがわかればいいのですが。。まだ慣れないものですいませんでした。

  • -1.#IND00と出てしまうのですが・・・

    vc++(2010)でガウスの消去法を使って連立方程式を解く、というプログラムを組みました。 正直中身自体をきちんと理解していないので、 組みながら理解しようと思って組んだのですが、 結果に-1.#IND00と出てしまいました。 これは何なのでしょうか? 下記がそのプログラムです。 #include<stdio.h> #include<math.h> #define N 3 int main(void){ double a[N][N+1] = {{2,3,4}, {3,-2,5}, {5,4,-7}}; double b[1][N+1] = {20,14,-8}; double x[N]; int i = 0; int j = 0; int k = 0; int l = 0; int pivot = 0; double p = 0; double q = 0; double m = 0; for(i = 0; i < N; i++){ x[i] = 0; } for(i = 0; i < N; i++){ pivot = i; for(l = i; l < N; l++){ if(fabs(a[l][i]) > m){ m = fabs(a[l][i]); pivot = l; } } if(pivot != i){ for(j = 0; j < N; j++){ b[0][j] = a[i][j]; a[i][j] = a[pivot][j]; a[pivot][j] = b[0][j]; } } } for(k = 0; k < N; k++){ a[k][j] = a[k][j] / p; a[k][k] = 1; for(j = k; j < N; j++){ a[k][j] = a[k][j] / p; } for(i = k+1; i < N; i++){ q = a[i][k]; for(j = k+1; j < N; j++){ a[i][j] = a[i][j] - q*a[k][j]; } a[i][k] = 0; } } for(i = N-1; i >= 0; i--){ x[i] = a[i][N]; for(j = N-1; j > i; j--){ x[i] = x[i] - a[i][j] * x[j]; } } // for(i = 0; i < N; i++){ // for(j = 0; j < N+1; j++){ // printf("%.1f", a[i][j]); // } // printf("\n"); // } // printf("解\n"); // for(i = 0; i < N; i++){ // printf("%f\n", x[i]); // } return 0; } 最後のコメントにしてある行は解を表す時と行列を表す時で使い分けているので、 実際はどちらかを外して使用しています。

  • 行列の計算

    #include<stdio.h> #define N 2 #define M 3 void hyoji(float[][M]); int main(){ int i,j,k; float a[N][M] = {{2.0,2.0,2.0},{2.0,2.0,2.0}}; float b[M][M] = {{1.0,1.0,1.0},{2.0,2.0,2.0},{1.0,1.0,1.0}}; float c[N][N]; for(i=0; i<N; i++){ for(j=0; j<M; j++){ c[i][j] = 0; for(k=0; k<M; k++){ c[i][j] += a[i][k] * b[k][j]; } } } hyoji(c); return(0); } void hyoji(float x[][M]){ int i,j; for(i=0; i<N; i++){ for(j=0; j<M; j++){ printf("%4.1f ",x[i][j]); } printf("\n"); } } 以上のプログラムで 行列aと行列bをかけ合せた行列cを求めるのですが コンパイルすると 8 8 8 8 8 1 となり、正しい結果がでません。 なにが間違っているのでしょうか?? よろしくお願いします。

  • 正しい結果が表示されない

    以下のプログラムはガウスの消去法を使って 解を求めるプログラムです。 しかし、gauss関数にprintf関数を入れてコンパイルすると 正しい結果 5 3 1 0 0 がでますが、gauss関数にprintf関数をいれずmain関数に書くと 0 0 0 0 0 となります。 なぜでしょうjか?? #include<stdio.h> #include<math.h> #define N 5 void gauss(double a[N][N+1]); int main(){ double a[N][N+1] = { { 1,-1,-1,-1,-1, 1}, {-1, 1,-1,-1,-1,-3}, {-1,-1, 1,-1,-1,-7}, {-1,-1,-1, 1,-1,-9}, {-1,-1,-1,-1, 1,-9} }; double x[N]; int i; gauss(a); printf("\n[x]=\n"); /* x[i] を表示する */ for(i=0; i<N; i++){ printf(" %8.3lf\n", x[i]); } return(0); } void gauss(double a[N][N+1]) { int i,j,k,p; double m, pmax, s, x[N]; for(k = 0; k < N-1; k++){ /* ピボット操作 */ p = k; /* p, pmax の初期値 */ pmax = fabs(a[k][k]); for(i = k+1; i < N; i++){ /* 最大値を検索 */ if(fabs(a[i][k]) > pmax){ p = i; pmax = fabs(a[i][k]); } } if(fabs(pmax) < 1.0e-12){ /* 最大値がゼロに近い時はエラー */ fprintf(stderr, "too small pivot!\n"); exit(1); } if(p != k){ /* ピボット操作 */ for(j = 0; j < N+1; j++) { s = a[k][j]; /* 値の入れ替え */ a[k][j] = a[p][j]; a[p][j] = s; } } for(i = k+1; i < N; i++) { /* 第 i 行 */ m = a[i][k] / a[k][k]; /* 倍率 m を計算 */ a[i][k] = 0; /* 注1 (下記参照) */ for(j = k+1; j < N+1; j++) { /* 第 j 列 */ a[i][j] = a[i][j] - a[k][j] * m; } } } for(i = N-1; i >= 0; i--){ /* 後退代入 */ m = 0; for(j = N-1; j > i; j--){ m = m + a[i][j] * x[j]; } x[i] = (a[i][N] - m) / a[i][i]; } }

  • ガウス消去

    行列3*3で4列目に答えが入る、ガウス消去の前進消去のプログラムを考えたのですが、3行目まで正規化してしまいます。 前進消去したのを行列mに格納しています。 int main() { int i, j, k,n=3; double a[3][4]={{ 3, 2,-3,-2}, { 2,-2, 1, 7}, {-3, 6, 5,28}}; double m[3][4]; /* 前進消去 */ for( i = 0; i < n; i++ ) { for( j = i+1; j <= n; j++ ) { m[i][j] = a[i][j]/a[i][i]; m[i][i]=1; for( k = i+1; k <= n+1; k++ ) { a[k][j] = a[k][j] -a[k][i] * m[i][j]; m[j][i]=0; }}}

  • 変数に入る値

    以下の1部のコードがあるとします。 #include<stdio.h> #define N 3 #define M 3 int main(){ float i,j,k;    ・    ・ここのプログラムは省略します。    ・ for(i=0; i<N; i++){ for(j=0; j<N; j++){ for(k=0; k<M; k++){ c[i][j] += a[i][k] * b[k][j]; }}} このようなコードがあった場合、c[i][j] += a[i][k] * b[k][j];のところで 3個目のfor文の1回目のループの時、 c[i][j] += a[i][k] * b[k][j];の[i][j]や[i][k]、[k][j]にはいる値は c[0.000000][0.000000]+=a[0.000000][0.000000]~~~~~~~~ とかんがえられるでしょうか? i,j,kはint型のほうがよいですが、確認のためfloatにしました。 意味不明な質問ですみません。 よろしくお願いします。

専門家に質問してみよう