2017年09月20日
《その38》 他の関数の呼出し(p.213演習6-7,演習6-8,演習6-9 )
新版明解C++入門編 p.213 演習6-7
引数 mで指定された月の季節を表示する関数 print_season を作成せよ。mが 3, 4, 5であれば「春」、6, 7, 8であれば「夏」、9, 10, 11であれば「秋」、12, 1, 2であれば「冬」と表示し、それ以外の値であれば何も表示しないこと。
void print_season(int m);
// p213_演習6-7
#include <iostream>
using namespace std;
void print_season(int m)
{
switch (m) {
case 12:
case 1:
case 2: cout << "冬\n"; break;
case 3:
case 4:
case 5: cout << "春\n"; break;
case 6:
case 7:
case 8: cout << "夏\n"; break;
case 9:
case 10:
case 11: cout << "秋\n"; break;
}
}
int main()
{
int month;
do {
cout << "何月(99で終了):"; cin >> month;
print_season(month);
} while (month != 99);
}
新版明解C++入門編 p.213 演習6-8
List 6-8 の関数 put_stars を、その内部で List 6-9 の関数 put_nchar を呼び出すことによって表示を行うように書きかえたプログラムを作成せよ。
// p213_演習6-8
#include <iostream>
using namespace std;
void put_nchar(int n, char c)
{
while (n-- > 0)
cout << c;
}
void put_stars(int n)
{
put_nchar(n, '*');
}
int main()
{
int n;
cout << "段数は:"; cin >> n;
for (int i = 1; i <= n; i++) {
put_stars(i);
cout << '\n';
}
}
新版明解C++入門編 p.213 演習6-9
a以上 b未満の乱数を生成して、その値を返却する関数 random を作成せよ。内部で乱数を生成する標準ライブラリである rand関数(p.30)を呼び出すこと。
int random(int a, int b);なお、bの値が a未満である場合には、aの値をそのまま返却すること。
演習6-9のプログラムを作って動作を確認する中で、srand関数の使い方について気付いたことがあります。以下に、失敗例 と 改善例 という形にまとめてみました。
【失敗例(srand関数の使い方)】
a以上 b未満の乱数を生成するだけのプログラムです。5回繰り返すので、すべて a = 1000, b = 2000 の値を与えて、乱数を生成させてみました。
#include <ctime>
#include <cstdlib>
#include <iostream>
using namespace std;
int random(int a, int b)
{
srand((unsigned int)time(NULL));
return (a + rand() % (b - a));
}
int main()
{
int a, b;
int n = 5;
while (n--) {
cout << "a と b (a < b)を入力 : "; cin >> a >> b;
cout << "生成した乱数 … 『 " << random(a, b) << " 』\n";
cout << "------\n";
}
}
これでは 1000以上 2000未満の乱数とは言えません。すべて 1500代〜1600代に集中しています。しかも、値が徐々に増加しているようです。
どこに問題があるのか いろいろ考えましたが、おそらく、srand関数に与えている乱数のタネに問題があるのだと思います。
毎回、時間の値をタネとして与えて rand関数で発生する最初の乱数を表示させているわけですが、与える時間の値がそれほど違っていないので、発生する乱数の最初の値も似かよった数値になってしまうものと思われます。
時間の値が大きくなっていくにつれて 発生する乱数系列の最初の値も大きくなるというのは、欠陥のようにも感じますが、多分、乱数の使い方として、毎回 srand関数を使うという方法が間違っているのだと考えます。
【改善例(srand関数の使い方)】
失敗例での考察から、srand関数の位置を変えて 1回だけ使用し、あとは、その乱数系列の値を rand関数で順に使用するようにしました。
#include <ctime>
#include <cstdlib>
#include <iostream>
using namespace std;
int random(int a, int b)
{
// srand((unsigned int)time(NULL));
return (a + rand() % (b - a));
}
int main()
{
srand((unsigned int)time(NULL));
int a, b;
int n = 5;
while (n--) {
cout << "a と b (a < b)を入力 : "; cin >> a >> b;
cout << "生成した乱数 … 『 " << random(a, b) << " 』\n";
cout << "------\n";
}
}
なんとかなったみたいです ε-(^ ^;)
「srand関数の使い方なんか常識でしょ!」という人には、
すみません、おさわがせしました m(_ _;)m
とりあえず、以下が 演習6-9 のプログラムです。
// p213_演習6-9
#include <ctime>
#include <cstdlib>
#include <iostream>
using namespace std;
int random(int a, int b)
{
int rnd;
if (a < b)
rnd = a + rand() % (b - a);
else
rnd = a;
return rnd;
}
int main()
{
srand((unsigned int)time(NULL));
int a, b;
cout << "a = 999 で終了\n";
do {
do {
cout << "小さいほうの値a(0以上): "; cin >> a;
if (a == 999) goto Exit;
cout << "大きいほうの値b(0以上): "; cin >> b;
} while (a < 0 || b < 0);
cout << "生成した乱数 … 『 " << random(a, b) << " 』\n";
cout << "------\n";
} while (1);
Exit:
;
}
--
この記事へのコメント
コメントを書く
この記事へのトラックバックURL
https://fanblogs.jp/tb/6722022
※ブログオーナーが承認したトラックバックのみ表示されます。
この記事へのトラックバック