OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

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

  • すぐに回答を!
  • 質問No.243541
  • 閲覧数127
  • ありがとう数1
  • 気になる数0
  • 回答数6
  • コメント数0

お礼率 22% (6/27)

配列とポインタでの書き直し(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
通報する
  • 回答数6
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

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

  • 回答No.5
レベル12

ベストアンサー率 40% (201/496)

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);  // エラー計算
 結果表示処理();
}
のようにすっきりすると思います。
-PR-
-PR-

その他の回答 (全5件)

  • 回答No.1
レベル12

ベストアンサー率 67% (310/456)

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

それよりも,
switch(roll) { .... }

sum[roll-2]++;
に置き換えることができます。
こちらのほうが,ポインタより重要かも。
補足コメント
lilno

お礼率 22% (6/27)

補足なのですが、この課題では A CASE statement for the count of the number of times that a given sum occurs. と書かれてあり、SWITCH を授業で習ったので、絶対使わないといけないらしいのですが、私自身もなんだか読みにくいプログラムになってしまったなぁって思っております、、、。その部分をSWITCHの別の使い方とかであてがうことはできないんでしょうか?case の使い方私のようなやりかたで正解なのでしょうか?
投稿日時 - 2002-03-30 17:50:19
  • 回答No.2
レベル9

ベストアンサー率 33% (33/98)

正直、何をしたいのか?何がわからないのか?がさっぱりわかりません。 問題を絞ってください。 下の方もかかれているので繰り返すのも何ですが、 errorへの代入やsumのインクリメントは一文にするべきです(みやすい、バグを出しにくい(修正しやすい)) まぁ、どつぼにはまることもありますが(範囲外アクセスなど、注意しないといけませんが) C/C++の場合配列名が、その配列の先頭へのポインタと ...続きを読む
正直、何をしたいのか?何がわからないのか?がさっぱりわかりません。
問題を絞ってください。

下の方もかかれているので繰り返すのも何ですが、
errorへの代入やsumのインクリメントは一文にするべきです(みやすい、バグを出しにくい(修正しやすい))
まぁ、どつぼにはまることもありますが(範囲外アクセスなど、注意しないといけませんが)

C/C++の場合配列名が、その配列の先頭へのポインタとして利用できます。

int array[10];
中略
*(array+0) = 0 /* array[0] = 0 と同じ */
*(array+1) = 1 /* array[1] = 1 と同じ */

後、throws という変数名は紛らわしいのでやめた方がいいと思います(throwが予約語です。かといってtryも予約語ですが、、、countじゃわかりにくいですか?(指定されてたらよけいなお世話なんですが
  • 回答No.3

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

ベストアンサー率 61% (70/113)

そもそも宣言以外では一次元配列とポインタは同じものだと思いますが。 無理矢理書き換えるなら array_name[index] を全て *(array_name+index) に変えれば(例:sum[i]を*(sum+i)に変える)変えたと言えなくもないかな、という程度でしょう。 それよりも、他の部分に課題があります。 ・「エラー」と書かれているが、error(誤差)の誤訳と思われる ...続きを読む
そもそも宣言以外では一次元配列とポインタは同じものだと思いますが。
無理矢理書き換えるなら
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()を使用するとすっきり書けます。
  • 回答No.6
レベル12

ベストアンサー率 67% (310/456)

おおっと。よくみたら,ちゃんとポインタ使ってますね。 << getError(probability, k, error) << endl; このgetErrorの引数 error が,配列 error[] の先頭のアドレスを示すポインタになっています。ということは,課題として,もとから問題はなかった!! 配列 arrayを関数に渡す際は,値渡し value arg ...続きを読む
おおっと。よくみたら,ちゃんとポインタ使ってますね。

<< 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.
とか,やはりあって欲しいなぁ。
このQ&Aで解決しましたか?
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ