シード番号を変更しない場合、Rand()関数は、実行するたびに同じ番号を生成することを理解しています。それがsrand()の出番です。時間は常に変化するので、time(null)パラメーターをsrandに渡す必要があることを知っています。私の質問は、チュートリアルサイトの以下のコードです。
int main()
{
int i, n=5;
time_t t;
/* Intializes random number generator */
srand((unsigned) time(&t));
/* Print 5 random numbers from 0 to 50 */
for( i = 0 ; i < n ; i++ ) {
printf("%d\n", Rand() % 50);
}
return(0);
}
ブランドからのリンクが表示されません
((unsigned) time(&t));
とランド。
printf("%d\n", Rand() % 50);
ランドとスランドの関係はどこにありますか?つまり、Rand()はsrand()から何らかのパラメーターを取得するため、毎回異なる数値を生成することを前提としています。私はそれがRand(srand(time(null));
それは、変数を使用せずに初期化するようなものです。 srandは初期化されていますが、使用されているようには見えません。
ランドはランドの前に最初に呼び出されるため、ランドは異なる数値を生成しますか?
乱数シードはグローバルな静的変数です。 Rand
とsrand
の両方にアクセスできます。
srand()
は、Rand
によって使用されるシードを設定し、「ランダムな」数を生成します(通常は疑似乱数なので引用符で囲みます)。 srand
を最初に呼び出す前にRand
を呼び出さないと、srand(1)
を呼び出してシードを1に設定したようになります。
多くのコードは現在の時刻をシードとして使用して、各プログラムが異なる乱数シーケンスを使用するようにしますが、デバッグ中に再現性の目的でいつでもsrand(42)
のようなものに変更できます。そして、time()
への呼び出しは実際には必要時間を入れる変数ではありません。単にNULLを渡すことができます:
_srand (time (NULL));
_
全体は、標準(_ISO C99 7.20.2.2 The srand function
_)に示されている例のように、単一のファイルで実装できます。
_// Rand_MAX assumed to be 32767.
static unsigned long int next = 1;
void srand(unsigned int seed) { next = seed; }
int Rand(void) {
next = next * 1103515245 + 12345;
return (unsigned int)(next/65536) % 32768;
}
_
next
がファイルの先頭にある静的変数であるという事実は、ファイルの外側のすべてに対しては見えないが、内側のすべてに対しては見えることを意味します(ローカライズされたグローバルの一種)。これが、srand()
とRand()
の間の通信方法です。
(幸運なことに)Rand()
を設計した人は、stdioからFILE
の中にあるものが見えないのと同じように、実装の詳細を保持することにしたので、リンクは表示されません。 ;欠点は、その状態をジェネレーターへのパラメーターではなく、グローバル(ただし非表示)変数にすることにしたことです。
これとは対照的に、非推奨のRand_r()
:状態は符号なし整数(> = 32ビットと想定)です。つまり、forbidden状態がそれよりも大きい、より良いジェネレーター、単にそれを格納するスペースがないからです!
代わりに、内部状態を非表示にしておくと、初期化なしでRandを呼び出すことがsrandを呼び出すことと同じであることが保証されている限り、最適なアルゴリズム(速度、周期など)を自由に選択して舞台裏で使用できますseed == 1で。
Paxdiabloは、C標準の例を示しました。 Rand/srandの後ろに隠すことができる別のジェネレーターを使用した例については、例えば http://en.wikipedia.org/wiki/Multiply-with-carry を参照してください。
余分に明確にするために:Rand_r
が適切に設計されていれば、Rand_t
(整数、構造、配列など)のような不透明な型があります。次のように、Rand_r
といくつかの架空のsrand_r
に渡します。
Rand_t state;
srand_r(&state, 1);
n = Rand_r(&state);
Rand関数は、state
変数が1つしかないことを除いて、まったく同じです。
Randは、擬似乱数列を提供します。
この番号は、呼び出されるたびに明らかに関連のない一連の番号を返すアルゴリズムによって生成されます。このアルゴリズムはシードを使用してシリーズを生成します。このシリーズは、関数srandを使用して特定の値に初期化する必要があります。
srandは、呼び出し中のリスト内のある場所へのポインターを設定します。各試行で呼び出したり、与えたりしない場合修正シードを使用すると、同じシーケンスが得られます。多くの人が、現在の秒をシードとして与えることを提案しています。ただし、同じ秒でコードを2回実行すると、同じシーケンスが得られます。
Srandの呼び出しで使用されるすべての異なるシード値について、擬似乱数ジェネレーターは、Randの後続の呼び出しで異なる連続した結果を生成することが期待できます 詳細説明