2016-03-25 11 views
-1
#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

void sep_gen(void); 

int main() 
{ 
srandom((unsigned)time(NULL)); 
printf("Random Numbers\n"); 

sep_gen(); 
sep_gen(); 
sep_gen(); 

return(0); 
} 

void sep_gen(void) 
{ 
long int r; 
int i; 

for (i=0;i<10;i++) 
    putchar('-'); 
putchar('\n'); 

r=random(); 
printf("%ld\n",r); 
} 

上記のコードは、3つの異なる整数を生成します。しかし、srandom((unsigned)time(NULL))がsep_gen()関数で使用されている場合、生成される整数はすべて3回同じです。 (以下コード)srandom(time(NULL))はmain()関数とユーザー定義関数の動作が異なるのはなぜですか?

#include <stdio.h> 
#include <stdlib.h> 
#include <time.h> 

void sep_gen(void); 

int main() 
{ 
printf("Random Numbers\n"); 

sep_gen(); 
sep_gen(); 
sep_gen(); 

return(0); 
} 

void sep_gen(void) 
{ 

srandom((unsigned)time(NULL)); 
long int r; 
int i; 

for (i=0;i<10;i++) 
    putchar('-'); 
putchar('\n'); 

r=random(); 
printf("%ld\n",r); 
} 

は、私の質問は、なぜsrandom()が機能したときにランダム()関数は異なる番号を生成していることであるメイン関数に配置されますが、そうsep_gen()関数を実行しませんか?

+0

'srandom'は標準機能ではありません。 – Olaf

+0

@Olaf:これは[manページ](http://linux.die.net/man/3/srandom)によるPOSIX.1-2001の一部です。なぜそれが重要かわからない。 – ShadowRanger

+0

@ShadowRanger:[ask]と[mcve]とは何かを参照してください。例えば、適切なタグが存在する。 POSIX、それ以外の場合は、テキストに記述する必要があります。 – Olaf

答えて

2

sep_genを入力すると、1回のプログラム実行ではなく、sep_genが呼び出されるたびに再インストールされます。そして、timeはエポックから秒を返しています。あなたのプログラムはsep_genを同じ秒間に3回呼び出す可能性があるので、randomコールの前に一定の開始点に再シードします。

基本的には、プログラムはランダムなソースを1回だけシードするか、何らかの理由で再シードする必要がある場合は、十分に変化しないシードソースを使用しないようにする必要があります。あなた自身を繰り返さずに再シードする本当にシンプルなアプローチは、srandom(time(NULL)^random());のようなものになるので、ジェネレータの既存の状態は、不十分に変化する外部種子源time()を摂動させます。これはおもちゃの例にすぎません(timeで絶え間なく混乱しても、予想される動作に大きな変化はありません)。より複雑なシナリオでこれをどうやって行うかについてのメモです。

+0

あなたは再シンプルなアプローチを詳しく教えていただけますか?srandom(time(NULL)^ random());あなたがそれが期待された振る舞いに大きな変化をもたらさないと言ったときのことを意味するのですか?謝罪、私は初心者ですので、私はその部分に従いませんでした。 –

+0

@ArshithaBasavaraj:それは既存のストリームから値を引き出す ' fはランダムで、ビットは「time」と排他的または排他的である。だから、種子には「ランダム性」という2つの情報源があります。最後の種蒔きに何が入ったのか、それ以降何回ランダム化されたのですか(この場合は毎回再シードされます)。ビット単位のxorは、2つの値がお互いのビットをトグルすることを意味します。ほとんどの場合、 'ランダムな'ストリームが予測可能であるため、動作が大きく変わることはありません。プログラムが起動した時間が分かっていれば、ランダムなストリームを再現することができます。 – ShadowRanger

2

これは、コードの高速処理によるものです。 srandomは乱数ジェネレータの種をリセットします。関数内で呼び出すと、関数を呼び出すたびに現在の時刻に更新されます。計算は非常に高速で、すべての呼び出しで同じ時刻が取得されるため、同じ番号が与えられたシードの最初のシーケンス番号として生成されています。

+0

シードが同じ値にリセットされないように一度だけ呼び出されます – greenshade

+0

0で連続する整数のシーケンスを初期化すると考えてください。 0、1、2、3などが得られます。0になるたびにリセットすると、0、0、0が得られます。 – greenshade

+0

メイン関数にはどのような変更がありますか? (申し訳ありませんが私の質問を繰り返して) –

関連する問題