• ベストアンサー

初期化しているつもりなのに、初期化されずにrand関数の結果を得る

皆様。こんにちは。 C++で簡単なプログラムを書いていたつもりでしたが、 コンパイルが正常であった後に、 プログラムを動作させてみたら、 自分の意図とは少し異なる結果となり、 どこが違うのか?が どうも自分では分かりかねてしまい、 アドバイスをいただきたく 質問させていただきました。 以下の例にあるように、 「a」と「b」という2文字の間に ランダム関数で作成した「任意の数字」を挟む処理を行い その結果を画面に表示するつもりです。 また、この処理を「num」で指定した回数分だけ 実行させたいと思っていました。 ■表示させようとした結果:「a」+「生成した乱数」+「b」 ■担当プログラム ------------------------------------------------------ for (int i=0; i<num; i++) { std::stringstream keystream ; srand((unsigned)time(NULL)); // 乱数の初期化 int randomnum = rand()% 109999999; // 乱数の生成 keystream << "a" << randomnum << "b" ;    printf(keystream); } ------------------------------------------------------ しかし、実際には、 指定された回数分だけの、 表示結果は得られるものの、 a123456b a123456b a123456b a123456b a123456b 上記例(num=5)のように、 乱数の部分が、全部同じ乱数となっていました。 しかし、forの中で 新たに乱数を生成する際、 生成する前に、 乱数の初期化をしているつもりでいますので、 プログラムを実行させた場合に、 表示させれた結果が、 どうして全て同じ乱数を得ているのか?が分からないでいます。 何かアドバイスいただけるとありがたいです。 宜しくお願い致します。

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

  • ベストアンサー
回答No.1

> 乱数の初期化をしているつもりでいますので、 > プログラムを実行させた場合に、 > 表示させれた結果が、 > どうして全て同じ乱数を得ているのか?が分からないでいます。 毎回初期化してるからです。 srand を for-loop の外に追い出して 「一度だけ」初期化しましょう。

stadiumk
質問者

お礼

早期にご回答いただきまして ありがとうございました! 正に、正に、 そのとおりでした! いい勉強になりました。 大変感謝しております。

その他の回答 (1)

  • php504
  • ベストアンサー率42% (926/2160)
回答No.2

srand( )は乱数のシードを設定する関数ですがこれに同じ値を指定するとrand( )で得られる数値も同じになります。 srand( )の引数にtimeを指定していますがパソコンはかなり高速に実行されるのでループの間timeの値も一定になってしまいその結果rand( )の値も同じになるわけです。 srand( )はプログラムの最初に1回だけ実行するようにしましょう。

stadiumk
質問者

お礼

php504さん ご回答いただきまして、 ありがとうございました! 初期化の件、とても参考になりました! 問題解消できました! 大変感謝しております。

関連するQ&A

  • rand関数について

    rand関数で取得した乱数を入力し、入力した逆の順番に表示しなさい、という問題があるのですが。一度乱数のプログラムを作り、その後逆に表示するプログラムというのは分かるのですが、そのあとがどうしても分かリません。 一般に、この場合は先ず。 #include <stdio.h> #include <stdlib.h> int main(void) { int i; for(i=1;i<==10;i++){ printf("%d",rand()%10+1); { return 0; } の表示をして、新たに逆にする表示をすると思うのですが、どのパターンを使うのが無難なのでしょうか? できれば 式を含めてお願いします。

  • rand関数

    PICをC言語(CCSC)で乱数のプログラムを作りたいと思っています。 乱数ルーチン1 srand(a) i_11=rand() i_12=rand() i_13=rand() . . 乱数ルーチン2 srand(b) i_21=rand() i_22=rand() i_23=rand() . . 乱数ルーチン1をCallした後(電源をOFFしないで)乱数ルーチン2をCallした場合 においてa=bならば i_11,i_12,i_13...i_21,i_22,i_23...は乱数だが i_11=i_21 i_12=i_22 i_13=i_23になってしまう・・・ということでしょうか? もし間違っていたら正解を教えてください。

  • Javaのプログラムで・・・

    Javaのプログラムで1~20までの整数乱数を実行後に指定回数だけ発生させ、そのうち何%が奇数であったかを表示するプログラムを作成中です。 乱数を発生させるところまでは行ったのですがここからどのように計算していくのかわかりません。 以下が作成したものですがアドバイスお願いします。 import java.io.*; public class Rand { public static void main(String args[]) throws IOException { System.out.print("発生させる乱数の回数は?"); BufferedReader br= new BufferedReader(new InputStreamReader(System.in)); String str = br.readLine(); int num= Integer.parseInt(str); for(int i=1;i<=num;i++){ int a=(int)(20*Math.random()+1); System.out.println(a); } for(int a=1; a<=;a++){ if(a%2==1); System.out.println("発生した乱数の"++"%が奇数です。"); } } }

  • 乱数の取得

    キー操作をした時に複数の乱数を習得させようと思っています。 【キ─操作関数】  int num[3] = {11, 22, 33}; ←初期化のため数字は適当です。  srand((unsigned int)time(NULL))  for(int i=0; i<=3; i++)  {   num[i] = rand % 10;  } 上記のプログラムを書いています。 num[0]、num[1]、num[2]にそれぞれ0~9の乱数が入ると思うのですが、 num[0]にしか乱数が入りません。 num[1]、num[2]には同じ数字(恐らくtimeで取得した数字?)が入っています。 何かお気づきの点がありましたらアドバイスお願い致します。

  • あるプログラムの結果がうまく表示されません

    以下のプログラムを書いたのですが、結果が正確に表示されません。 どこが間違っているのでしょうか? プログラムの内容は10個の整数を入力し、更に入力した数字で割れる個数を表示するものです。 #include <stdio.h> void input_i(int *in, int num); int div_enable(int *in, int num, int divisor); int main(void) { int array[10]; int i, s_num; input_i(array, 10); scanf("%d", &s_num); i = div_enable(array, 10, s_num); printf("%d\n", i); return 0; } void input_i(int *in, int num) { int i; for(i=0; i<num; i++){ scanf("%d", in+1); } } int div_enable(int *in, int num, int divisor) { int cnt, i; cnt = 0; for(i=0; i<num; i++) { if(in[i]%divisor == 0){ cnt++; } } return cnt; }

  • 関数について

    C言語の勉強をしているのですが、関数のところがよく理解できません。 ------------------------------ #include <stdio.h> int beki(int a, int b); int main(void) { int n; n=beki(2,3); printf("%d\n",n); printf("%d\n",beki(3,4)); } int beki(int a, int b) { int i,ans; ans=1; for(i=1; i<=b; i++) { ans=ans*a; } return ans; } ---------------------------- 実行結果 8 81 ----------------------------- 上のサンプルで int i,ans; ans=1; for(i=1; i<=b; i++) { ans=ans*a; } の部分は、解説書には「渡されたデータa,bを使って戻り値ansを計算 している」「aのb乗を計算している」などとありましたが、なぜaのb乗を計算しているのでしょうか?実行結果が8と81の何に関係しているのでしょう? ansやa,bの値を求めたら、何の値になるのでしょうか? これらについて、解説をお願いいたします。

  • realloc関数の使い方

    前回のmalloc関数の使い方の続きみたいな感じです。 参考書にはmalloc関数とcalloc関数については載っていましたがrealloc関数については記述はありませんでした。 realloc関数はメモリの拡張や縮小ができるというみたいなのでdo~while文の中に入れています。 どこが間違っているのでしょうか。 /* 課題3-6 */ #include <time.h> #include <stdio.h> #include <stdlib.h> int user; /* プレーヤの手 */ int comp; /* コンピュータの手 */ int win_no; /* 勝った回数 */ int lose_no; /* 負けた回数 */ int draw_no; /* 引き分けた回数 */ int *a; int *b; int *a1; int *b1; int i; int stage = 0; char *hd[] = {"グー", "チョキ", "パー"}; /* 手 */ /* initialize関数の宣言 */ void initialize(void); /* jyanken関数の宣言 */ void jyanken(void); /* count_no関数の宣言 */ void count_no(int result); /* disp_result関数の宣言 */ void disp_result(int result); /* confirm_retry関数の宣言 */ int confirm_retry(void); /* rireki関数の宣言 */ void rireki(void); /* メイン関数 */ int main(void) { int judge; /* 勝敗 */ int retry; /* もう一度 */ initialize(); /* 初期処理 */ a = (int *)calloc(5, sizeof(int)); b = (int *)calloc(5, sizeof(int)); do{ jyanken(); /* じゃんけん実行 */ /* コンピュータとプレーヤの手を表示 */ printf("私は%sで、あなたは%sです。\n", hd[comp], hd[user]); judge = (user - comp + 3) % 3; /* 勝敗を判定 */ count_no(judge); /* 勝/負/引分け回数を更新 */ disp_result(judge); /* 判定結果を表示 */ retry = confirm_retry(); a1 = (int *)realloc(a, sizeof(int) * (draw_no+lose_no+win_no+1)); b1 = (int *)realloc(b, sizeof(int) * (draw_no+lose_no+win_no+1)); rireki(); }while(retry == 1); for(i=0; i<draw_no+lose_no+win_no; i++){ printf("%d回目 ユーザ%c コンピュータ%c\n", i+1, hd[b1[i]], hd[a1[i]]); } printf("%d勝%d敗%d分けでした。\n", win_no, lose_no, draw_no); free(a); free(b); return (0); } /*--- 初期処理 ---*/ /* initialize関数の定義 */ void initialize(void) { win_no = 0; /* 勝った回数 */ lose_no = 0; /* 負けた回数 */ draw_no = 0; /* 引き分けた回数 */ srand(time(NULL)); /* 乱数の種を初期化 */ printf("じゃんけんゲーム開始!!\n"); } /*--- じゃんけん実行(手の読み込み/生成) ---*/ /* jyanken関数の定義 */ void jyanken(void) { int i; comp = rand() % 3; /* コンピュータの手 (0~2) を乱数で生成 */ printf("\n\aじゃんけんポン …"); for(i=0; i<3; i++) printf(" (%d)%s", i, hd[i]); printf(":"); scanf("%d", &user); /* プレーヤの手を読み込む */ } /*--- 勝/負/引き分回数を更新 ---*/ /* count_no関数の定義 */ void count_no(int result) { switch(result){ case 0: draw_no++; break; case 1: lose_no++; break; case 2: win_no++; break; } } /*--- 判定結果を表示 ---*/ /* disp_result関数の定義 */ void disp_result(int result) { switch(result){ case 0: puts("引き分けです。"); break; /* 引き分け */ case 1: puts("あなたの負けです。"); break; /* 負け */ case 2: puts("あなたの勝ちです。"); break; /* 勝ち */ } } /*--- 再挑戦するか確認 ---*/ /* confirm_result関数の定義 */ int confirm_retry(void) { int x; printf("もう一度しますか … (0)いいえ (1)はい:"); scanf("%d", &x); return (x); } /*--- 履歴の表示 ---*/ /* rireki関数 */ void rireki(void) { a1[stage] = comp; b1[stage] = user; stage++; }

  • RAND関数です

    お願いします。 A1~A20までに入力枠があります この数値は他の箇所より参照しています。 このA1~A20の数値に対してB1~B20に=RAND()で乱数を発生するようにしていますが、ただ、データー入りがA1~A20行が最大で、A1~A7までの時とか毎回変化します。当然、データーの入っていない行にも乱数が発生します。 =IF(ISERROR(RAND()))、” ”、((RAND())))) で表示させないようにとしましたが、できません。 関数の」組み合わせ?マクロのコード? いい方法がありませんでしょうか、宜しくお願いします。

  • 質問です。

    コンパイルはできるのですが、実行するとExption in thread"main"java.lang ArrayIndex0ut0fBoundsExcept ion :0 at java1_1.main(java1_1.java:19と表示をされてしまってできません。教えてください。宜しくお願いします。 /* 実行時引数を受け取り乱数を設定 */ class java1-1 { public static void array_syokika(int a[]) { for(int i = 0; i < a.length; i++) { a[i] = (int)(100 * Math.random()); } } public static void main(String args[]) { int num = Integer.parseInt(args[0]); int a[] = new int[num]; array_syokika(a); for(int i = 0; i < a.length; i++) { System.out.println("a[" + i + "]=" + a[i]); } } }

    • ベストアンサー
    • Java
  • 変数の初期値

    へんてこな質問かもしれません・・・ class Syokika{   public static void main(String args[]){     int[] a = new int[1];     System.out.println(a[0]);   } } を実行するとどうなるかという問題なのですが、 「変数が初期化されていない」 というエラーが出ると思っていたのですが、 答えは「0と表示される」でした・・・ で、解説を見ると、「配列が生成されるときに初期値が生成される。intの場合は0だ」と書いてありました。 でも、たんにint a;とした場合にaを参照しようとすると初期化されてないですよね・・・? これはどういうことなのでしょうか・・・?

    • ベストアンサー
    • Java

専門家に質問してみよう