C言語初心者のための調和平均プログラムの修正方法

このQ&Aのポイント
  • C言語初心者の方が調和平均のプログラムを作成している際にうまくいかない問題が発生した場合の解決方法について解説します。
  • 調和平均の計算式とは、n個の入力された数値の逆数の和を1で割った値です。ただし、0が入力された場合は値を返さないようにします。
  • プログラムの修正ポイントは以下の通りです。1) 0除算の回避、2) 数字の入力終了条件、3) 計算結果の表示方法です。それぞれの修正方法について詳しく解説します。
回答を見る
  • ベストアンサー

c言語です

c言語初心者です。今大学の課題でc言語のプログラムをかいているのですが、うまくいかないので助けて欲しいです。以下のようなプログラムで調和平均の値を出したいのですがなぜか表示されません。infと表示されてしまいます。あと調和平均とはn/(1/d1+1/d2+1/d3+.........+1/dn)の値です。ここでd1~dnは入力された数のことです。なので0が入力された場合は値を返さないようにしたいです。   どこをどのように直せばいいのか教えてください。よろしくお願いします。 #include <stdio.h> #include<math.h> #define M 1000 int main (int argc, const char * argv[]) { // insert code here... float d[M]; double e[M]; double wa=0.0,av,bun=0,kika=1,tyowa=0; /*avはaverageを,bunは分散を意味します*/ int i=0,j=0; printf("複数の数字を入力してください\n"); printf("数字入力を終了するときはnull文字を入力してください\n"); printf("数字以外が入力されたら\n"); printf("それまでの数字の計算結果を表します\n"); /*数字を入力、和を求める*/ while (scanf("%f",&d[i])!='\0') { wa=wa+d[i]; i++; } if (i!=0) { printf("算術平均は%fです\n",wa/i); av=wa/i; for (j=0; j<i; j++) { kika=kika*d[j]; } printf("幾何平均は%fです\n",pow(kika,1./i)); for (j=0; j<i; j++) { if (d[j]=0) { printf("調和平均は出せません\n"); } else e[j]=1/d[j]; } for (j=0; j<i; j++) { tyowa=tyowa+e[j]; } printf("調和平均は%fです\n",e[1]); for (j=0; j<i; j++) { bun=bun+(d[j]-av)*(d[j]-av); } printf("分散の値は%fです\n",bun/i); } else { printf("数字を入力してください\n"); } return 0; }

質問者が選んだベストアンサー

  • ベストアンサー
  • okormazd
  • ベストアンサー率50% (1224/2412)
回答No.4

いろいろあるようだが、参考にどうぞ。 #include <stdio.h> #include<math.h> #define M 1000 int main (void) /*引数はなくても*/ { // insert code here... double d[M],e[M]; /*d[M]もこれにした*/ double wa=0,av,bun=0,kika=1,tyowa=0; /*avはaverageを,bunは分散を意味します*/ int i=0,j=0; printf("複数の数字を入力してください\n"); printf("数字入力を終了するときはnull文字を入力してください\n");    /*null文字って?*/ printf("数字以外が入力されたら\n"); printf("それまでの数字の計算結果を表します\n"); /*数字を入力、和を求める*/ while (scanf("%lf",&d[i])!='\0') { /*doubleで入力、scanfの問題は別にしておく*/ wa=wa+d[i]; printf("%f\n",wa); i++; } if (i!=0) { av=wa/i; /*これが先のほうがいいだろう*/ printf("算術平均は%fです\n",av); /*で、avにした*/ for (j=0; j<i; j++) { kika=kika*d[j]; } printf("幾何平均は%fです\n",pow(kika,1./i)); for (j=0; j<i; j++) { if(d[j]==0.) { /*論理演算子ね*/ printf("調和平均は出せません\n"); return 0; /*ここで帰ったほうがいい*/ } else { e[j]=1./d[j];    /*e[j]に変える意味はあまりないようだが*/ } } for (j=0; j<i; j++) { /*この辺無駄があるようだがそのままにした*/ tyowa=tyowa+e[j]; } tyowa=i/tyowa; /*これじゃないと調和平均にならないのじゃないかな*/ printf("調和平均は%fです\n",tyowa); /*tyowaを表示*/ for (j=0; j<i; j++) { bun=bun+(d[j]-av)*(d[j]-av); } printf("分散の値は%fです\n",bun/(i-1)); /*不偏分散ならi-1、入力データを母集団とするならi*/ } //else { // printf("数字を入力してください\n"); /*これはいらないだろう*/ //}

その他の回答 (3)

  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

すでに指摘がありますが > if (d[j]=0) { これは、C言語では d[j]=0 の代入を実行→式全体は値は代入した値と等しい(==0)→値が0なので真偽値は「偽」→ifの条件は(常に)不成立 となります。 比較の==と代入の=を間違えるのは、よくある間違いの一つです。0 == d[j]のように定数を左辺に持ってくることである程度は防げますが、根本対策はありません。気をつけましょう。 あとは。 > float d[M]; と宣言していますが、他の計算をdouble使ってますし、精度的にも速度的にも、現在よくある 実行環境ではfloatを使う意味はほとんどありません。 doubleを使った方がよいでしょう。 > while (scanf("%f",&d[i])!='\0') { scanfの%fを%lfにすれば、対象がdoubleになります。 あと > printf("数字入力を終了するときはnull文字を入力してください\n"); とも絡むのですが。 scanfの戻り値をマニュアルで確認してください。 「入力できた値の数(全部失敗で0)/入力がEndOfFileになっていたらEOF」 となっているはずです。入力した文字や文字列を返すようにはなっていません。'\0'と比較しても、それはnull文字が入力されたことの判定にはなっていません。 '\0'は数値の0と同じなので、今回はたまたま、数字以外の文字を入力すればscanfが0を返してループから抜けますが、EndofFile(Unix 系ならCtrl+D,WindowsだったらCtrl+Z後リターン)を入力すると無限ループになります。 (もっとも、その前にd[M]の範囲外となりエラーで止ると思いますが) そもそもnull文字なんて入力できますか? > else e[j]=1/d[j]; 現行では、 (int)1 / (float)d[j] →暗黙の型変換でfloatで計算→暗黙の型変換でdoubleにしてe[j]に代入 となると思います。計算精度に効いてくるので、上記の通り、d[M]はdoubleで宣言しておきましょう。

  • sekibunx
  • ベストアンサー率61% (8/13)
回答No.2

#1です. 回答の補足です. if (d[j]=0) { このようにifの条件式で代入してしまうと, 0を代入した場合は常にfalse,0以外の場合は常にfalseになります. 今回は0を代入してますので,trueとなり続行しますが, d[j]が0となるのでe[j]はInfiniteになります. あとprintf("調和平均は%fです\n",e[1]);としていますが,これは1/d1を表示しているだけですね. tyouwa = (1/d1+...1/dn)なので,最終的な調和平均はn/tyouwaとなるのではないでしょうか.

  • sekibunx
  • ベストアンサー率61% (8/13)
回答No.1

計算式はあまり詳しく見てませんが... if (d[j]=0) { printf("調和平均は出せません\n"); } if(d[j]==0) の誤りですね.

関連するQ&A

  • C言語

    C言語 グループのモードについて 以下のプログラムは20個の数字を入力しモードを表示する物です。 処理の流れを詳しく解説出来る方がいましたらご教授願います。 #include <stdio.h> int main(void) { int stats[20],i,j; int mode,count,oldcount,oldmode; printf("20個の数字を入力して下さい:\n"); for(i=0;i<20;i++) scanf("%d",&stats[i]); oldcount=0; for(i=0;i<20;i++){ mode=stats[i]; count=1; for(j=i+1;j<20;j++) if(mode==stats[j]){ oldmode=mode; oldcount=count; } } printf("モードは%dです\n",oldmode); return 0; }

  • C言語!プログラム書いたのですがエラーです!

    課題内容 キーボードから数字を入力してその値までの合計を表示する。 さらに入力した値が偶数なら0から入力した値までのすべての偶数の和を 入力した値が奇数なら1から入力した値までのすべての奇数の和を表示するプログラム。 #include<stdio.h> int main(void) { int i, n, sum; sum=0; scanf("%d",&n); printf("入力値:%d\n", n); if(n%2 = 0) { for(i=0;i<=n;i+=2) { sum=sum+i; } printf("合計値:%d\n",sum); } else { for(i=1;i<=n;i+=2) { sum=sum+i; } printf("合計値:%d\n",sum); } return(0); } これでコンパイルすると10行目に左辺値が必要とでます。 どうすればよいでしょうか? 教えてください。よろしくお願いします。

  • C言語 構造体とvectorについてです

    C言語についてこんなプログラムをつくろうとしています。内容はこんなです↓↓ 1「番号・身長・体重を入力」←番号を入力するとこで0と入力するまでループ 2「今まで入力した値の平均を出力」←身長・体重それぞれの値の平均 3「番号を入力すると対応したデータ(1で打ち込んだデータ)を出力」 4「1を入力すると出力した値の修正をする」 3と4のループをして3のところで0を入力したら終了。。。 という感じです。 わからないとこは、最初のnumberの入力でデバックエラーがおきてしまうとこ(scanf("%d",&vec[i].number);の部分がおかしい?)、2は全体的にわかりません、3と4はなんとなくわかります。 構造体とvectorを使うのがわかりやすいと思って作成中ですが完全に止まってしまいました。 できれば1と2のプログラムを作成していただけませんか?よろしくおねがいします。 int main() { float height, weight; int i, b, D, P, J, M, E, number; vector<student_list> vec; student_list num; vec.push_back(num); for(i = 0;;i++) { printf("%d人目のデータです\n番号を入力して下さい\n", i + 1); scanf("%d",&vec[i].number); if(vec[i].number == 0) { return 0; } else { printf("身長と体重を入力して下さい\n"); scanf("%f\n%f",&vec[i].height,&vec[i].weight); printf("あなたのBMIは%.1fです\n",vec[i].weight*vec[i].weight/vec[i].height); printf("電子回路の点数を入力して下さい\n"); scanf("%d",&vec[i].D); printf("プログラミングの点数を入力して下さい\n"); scanf("%d",&vec[i].P); printf("国語の点数を入力して下さい\n"); scanf("%d",&vec[i].J); printf("数学の点数を入力して下さい\n"); scanf("%d",&vec[i].M); printf("英語の点数を入力して下さい\n"); scanf("%d",&vec[i].E); printf("国数英の平均点は%dです\n",(vec[i].J+vec[i].M+vec[i].E)/3); printf("5教科の平均点は%dです\n",(vec[i].D+vec[i].P+vec[i].J+vec[i].M+vec[i].E)/5); } } }

  • C言語 プログラミング 行列演算

    下記のプログラムのおかしい点と解決法を教えてください。 コンパイルは通りますがうまく動きません。。 #include<stdio.h> #define MAX 500 int main(void){ int matrA[MAX][MAX],matrB[MAX][MAX],matrC[MAX][MAX],l,m,n,i,j,k; printf("lとmを入力してください:"); scanf("%d",&l); scanf("%d",&m); printf("行列Aを入力してください"); for(i=0;i<l;i++){ printf(">"); for(j=0;l<m;j++){ scanf("%d",&matrA[i][j]); } printf("\n"); } printf("nを入力してください(m = %d):",m); scanf("%d",&n); printf("行列Bを入力してください"); for(i=0;i<m;i++){ printf(">"); for(j=0;j<n;j++){ scanf("%d",&matrB[i][j]); } printf("\n"); } printf("C=\n"); for(i=0;i<l;i++){ for(j=0;j<n;j++){ for(k=0;k<m;k++){ matrC[i][j]+=matrA[i][k]*matrB[k][j]; } printf("%d",matrC[i][j]); } printf("\n"); } }

  • C言語をお願いします

    何が違うのか教えてください。 segmentation faultになります。 よく分からないので、プログラムを作っていただければ、助かります。 問 整数を入力し、降順並び変えてに表示。 ・入力した整数は配列に入れ、その配列を使って並び変える(入力終りの印は 1000 とする)。 ・入力する整数の個数は #define NUM 100 を使いなさい。 ・使うデータは、下記の例のように、キーボードから入力すること。 #include<stdio.h> #define NUM 100 int main(void){ int d[NUM]; int temp; int i,j,n; printf("Input scores.\n"); for(i=0; i<NUM && d[i]!=1000; i++){ scanf("%d",&d[i]); } n = i; for(i = 0; i < n; i++){ for(j = i + 1; j < n;j++){ if(d[j] > d[i]){ temp = d[i]; d[j] = d[i]; d[i] = temp; } } } printf("After sort."); for(i=0; i < n; i++){ printf("%d\n",d[i]); } return 0; } 実行例 Input scores. 60 30 45 90 100 0 1000 After sort. 100 90 60 45 30 0 よろしければ 問2 並び変えをする部分を mysort 関数にしたプログラムを作ってください。 main 関数から mysort 関数には点数の個数と sort 前の配列を渡し、並び変え結果の表示はmain 関数でお願いします。 (問題の意味が分かりません) 関数はさっぱり分かりません。 では、お願い致します。

  • C言語について

    「キーボードから10個の実数を入力し、それらの平均を求めるプログラムを作れ。」という問題で私は、 #include <stdio.h> void main(void) { float A; float a,b,c,d,e,f,g,h,i,j; printf("実数を入力してください:"); scanf("%f",&a); scanf("%f",&b); scanf("%f",&c); scanf("%f",&d); scanf("%f",&e); scanf("%f",&f); scanf("%f",&g); scanf("%f",&h); scanf("%f",&i); scanf("%f",&j); A=(a+b+c+d+e+f+g+h+i+j)/10; printf("平均は%fです.\n",A); } と考えたのですが、もっとすっきりとしたプログラムはないのでしょうか?もっとシンプルにしたいのです。教えて下さい。よろしくお願いします。

  • C言語

    main() { int a = 5,b=2,e,f,g=3,i; double c,d,h=2.0; c = a/b; printf("c = %f\n",c); d = a/h; printf("d=%f\n",d); e = a++; f = ++b; g+= 4; i= ++a + b; printf(" a = %d\n",a); printf(" b = %d\n"b); printf(" e = %d\n"e); printf(" f = %d\n"f); printf(" g = %d\n"g); printf(" i = %d\n" i); 答え a=7,b=3,c=2.0,d=2.5,e=5,f=3,g=7,i=10 この問題のa,b,iがどうやってこの値になるのかがわかりません解説お願いします。

  • C言語 プログラミングで行詰まりました…

    標準入力(キーボード)からi,jk,nの値を入力し、次の漸化式を計算し、X_0からX_nまで求めるプログラムを作成したいのですが、うまく表示されません。どかがおかしいのかご指摘お願いします。 <漸化式> X_n=(a+b)/X_(n-1) , X_0=c(n=0) ================================================================== #include<stdio.h> float f_X(int a,int b,float c) { float y; y=(a+b)/c; return y; } int main (void) { int number,i,j; float k,l,n,X; printf("i:"); scanf("%d", &i); printf("j:"); scanf("%d", &j); printf("k:"); scanf("%f", &k); printf("n:"); scanf("%f", &n); X=k; printf("X_0= %.6f\n",X); for(number=1;number<=n;number++) { l=f_X(i,j,X); printf("X_%d= %.6f \n",number,l); X=l; } return 0; } ===================================================================

  • C言語で困っています...

    入力した数値の列だけ○と×を縦に、段々になるように表示する (最後の行は×にならなければいけない)プログラムを作成しています。 (実行例) ○と×を表示します。何列?:10            ×           ○×          ×○×         ○×○×         ×○×○×       ○×○×○×      ×○×○×○×    ○×○×○×○× ×○×○×○×○× ○×○×○×○×○× 途中までプログラミングできたのですが、 偶数の数値を入れたときはきちんと最後の行は×になっても 奇数の数値を入力すると○が最後の行になってしまい、うまくいきません。 どこがだめなのでしょうか? どなたか教えてください。 /* 入力した数値の列だけ、○と×を縦に、   段々になるように表示する(最後の行は×になる) */ #include <stdio.h> int main(void) { int i, j, n; printf("○と×を表示します。何列?:"); scanf("%d", &n); for (i=0; i<n; i++){ for (j=0; j<n; j++){ if (j >= (n - 1) - i){ if (j % 2 == 0) printf("○"); else printf("×"); } else printf(" ");//全角スペース } printf("\n"); } return 0; }

  • C言語について

    C言語の問題なのですか、作成したのですが内容がわからないです。テキストを読んでも解説が書いていないので、出来ればどなたか簡単な解説でも教えて頂けるとありがたい。 〈7-3〉 #include <stdio.h> int main(void) { int i, j; long kuku[9][9]; // 九九の値の代入処理を記述 for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { kuku[i][j] = (i + 1) * (j + 1); } } ///////////////////////////////////// // 九九の表示部(ここは変更しないこと) for (i = 0; i < 9; i++) { for (j = 0; j < 9; j++) { printf(" %2d", kuku[i][j]); } printf("\n"); } return 0; }

専門家に質問してみよう