• ベストアンサー

配列とポインタでの書き直しその2

配列とポインタでの書き直し(c++)その1 のつづき cout << endl; cout << setw(5) << "Sum" << setw(12) << "Number" << setw(14) << "Probability" << setw(10) << "Error" << endl; cout << "-----------------------------------------" << endl << endl; cout << setiosflags(ios::fixed | ios::showpoint); for (int k = 0; k <= 10; k++) { probability = static_cast<double>(sum[k])/throws; cout << setw(4) << k+2 << setw(12) << sum[k] << setprecision(6) << setw(14) << probability << setprecision(2) << setw(11) << getError(probability, k, error) << endl; } return 0; } // Roll two dice. int rollDice() { int dice1, dice2; dice1 = rand()%6 +1; dice2 = rand()%6 +1; return (dice1 + dice2); } // Example: for error dice 12 // // prob = sum[10] / throws, // // // |prob - e[10]| // error = ----------------- x 100 // e[10] // double getError(double p, int i, double e[]) { return ((fabs(p - e[i])/e[i])*100); } 関連URL: http://www.okweb.ne.jp/kotaeru.php3?q=243537

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

  • ベストアンサー
  • yatokesa
  • ベストアンサー率40% (201/496)
回答No.5

switch文をどこで使うか、見えてきませんでしたのでこの部分は割愛しますが、プログラム自体をもっとすっきりさせてみましょう。 処理のサブルーチン化です。現在メインの中にあるサイコロを指定回数分転がすところですが、これを  rolling (int* sum, int throws) として作ればポインタの課題はクリア、プログラムも見やすくなると思います。 また、結果を表示するとき、確率とエラー(?)の計算をやりながら出力していますが、これも予め別の配列をそれぞれ用意して、別のサブルーチン内で計算するようにしてみてください。 そうすると main関数内は main {  int sum[11];  double error[11], probability[11];  初期化処理();  rolling (sum, throws);  // サイコロを指定回数転がす  calc_prob (probability, sum, throws);  // 確率計算  calc_error (error, probability);  // エラー計算  結果表示処理(); } のようにすっきりすると思います。

その他の回答 (5)

  • onosuke
  • ベストアンサー率67% (310/456)
回答No.6

おおっと。よくみたら,ちゃんとポインタ使ってますね。 << getError(probability, k, error) << endl; このgetErrorの引数 error が,配列 error[] の先頭のアドレスを示すポインタになっています。ということは,課題として,もとから問題はなかった!! 配列 arrayを関数に渡す際は,値渡し value argument ではなく,参照渡し reference argument を使わねばならない。って,やつです。 しかし,課題の意図としては,'sum' を同じような形で,ポインタとして扱って欲しかったように思います。 yatokesaさんのご意見では,ちょうどそのような形になりますね。 > A CASE statement for the count of the number of times that a given sum occurs. これなら,あのswitch文もしょうがないですね。お上には逆らえません。 ん~でも, [Practice Exam. Q-2] Replace the SWITCH block as a 1-line-statement. とか,やはりあって欲しいなぁ。

  • zzzzzz
  • ベストアンサー率61% (70/113)
回答No.4

そもそも宣言以外では一次元配列とポインタは同じものだと思いますが。 無理矢理書き換えるなら array_name[index] を全て *(array_name+index) に変えれば(例:sum[i]を*(sum+i)に変える)変えたと言えなくもないかな、という程度でしょう。 それよりも、他の部分に課題があります。 ・「エラー」と書かれているが、error(誤差)の誤訳と思われる ・変数の名前付けに問題が多い(sumが回数を表したり、errorが確率の理論値を表したり) ・変数の名前付けが危ない(throwが予約語だと知ってthrowsという名前を付けているのか) ・基本型のstatic_castは明示の必要はない。(((double)sum[k])/throwsで十分) ・相対誤差を算出するgetError()関数の機能分離が不完全(iとeの両方を引数にするのは論理的におかしい。e[i]を引数にすべき) なお、sumの初期化は、memset()を使用するとすっきり書けます。

noname#30727
noname#30727
回答No.3

for などの繰り返し処理を、ポインタと++演算子を使ってアクセスせよという課題なのだとは思いますが、もう少し先読みすると、設計力を問われているような気もします。 1つの関数の守備範囲を単純化していく事を考えると、今は main 関数だけが長いですが、初期化関数、入力関数、ダイスを振ってサムを更新させる関数、結果の表示関数などに分割する事でプログラムは読みやすくなります。その結果、引数にもポインタを使う事になるはずです。

  • sssohei
  • ベストアンサー率33% (33/98)
回答No.2

正直、何をしたいのか?何がわからないのか?がさっぱりわかりません。 問題を絞ってください。 下の方もかかれているので繰り返すのも何ですが、 errorへの代入やsumのインクリメントは一文にするべきです(みやすい、バグを出しにくい(修正しやすい)) まぁ、どつぼにはまることもありますが(範囲外アクセスなど、注意しないといけませんが) C/C++の場合配列名が、その配列の先頭へのポインタとして利用できます。 int array[10]; 中略 *(array+0) = 0 /* array[0] = 0 と同じ */ *(array+1) = 1 /* array[1] = 1 と同じ */ 後、throws という変数名は紛らわしいのでやめた方がいいと思います(throwが予約語です。かといってtryも予約語ですが、、、countじゃわかりにくいですか?(指定されてたらよけいなお世話なんですが

  • onosuke
  • ベストアンサー率67% (310/456)
回答No.1

ポインタは教科書やWebで「配列をポインタに置き換える方法」を調べれば,すぐに分かるでしょう。 それよりも, switch(roll) { .... } を sum[roll-2]++; に置き換えることができます。 こちらのほうが,ポインタより重要かも。

lilno
質問者

補足

補足なのですが、この課題では A CASE statement for the count of the number of times that a given sum occurs. と書かれてあり、SWITCH を授業で習ったので、絶対使わないといけないらしいのですが、私自身もなんだか読みにくいプログラムになってしまったなぁって思っております、、、。その部分をSWITCHの別の使い方とかであてがうことはできないんでしょうか?case の使い方私のようなやりかたで正解なのでしょうか?

関連するQ&A