2017-02-03 7 views
-1

コードを実行すると、rand()関数は同じ非乱数を生成するようです(私の意図はvalueに乱数を生成することです)。 rand()の代わりに仮パラメータlengthを使用すると、コードが機能しているように見えます(数値が小さくなっているようです)。どこが間違っていますか?リンクリスト付きの再帰関数でrand()を使用する

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

struct node{ 
    int value; 
    struct node *next;  
}; 

struct node *construct(int); 

int main(){ 
    struct node *list = construct(5); 

    while(list){ 
     printf(" %i\n", list->value); 
     list = list->next; 
    } 

    return 0; 
} 

//It builds a list of "length" items recursively 
struct node *construct(int length){ 
    struct node *node = (struct node *) malloc(sizeof(struct node)); 

    srand(time(NULL)); 

    node->value = rand(); /* unclear part of code */ 

    if(length - 1){ 
     node->next = construct(length - 1); 
    } 

    return node; 
} 
/* missing the code to free memory */ 

/* example of output */ 
837240329 
837240329 
837240329 
837240329 
837240329 
+1

'rand'のドキュメントを読むのはどうですか? – Olaf

+0

「*同じ*」と同じ乱数?あなたは各ノードに同じ番号を持っていますか?各実行で同じ番号のシーケンス?あなたが投稿しているのは、要求された出力がありません。 – Prune

+4

'main'の先頭で' srand(time(NULL)); '* once *を呼び出します。 –

答えて

1

srand()関数は、シードを取り、擬似ランダム数生成器を初期化します。

擬似乱数ジェネレータはランダムではありません。代わりに、シードによって決定される非常に固定された数のシーケンスを生成します。異なる種子が異なる配列を生産するが、同じ種子は、数年後でも同じ配列を生成する。 (これは機能であり、動作が "ランダム"であるプログラムをデバッグすることができます)

construct関数を呼び出すたびに、乱数ジェネレータにシードが設定されます。これは間違っています。あなたのmain()機能でRNGを1回シードする必要があります。

あなたの構築機能はすぐに実行されます。あなたの種はtime()に基づいています。したがって、関数が非常に素早く終了するので、同じ結果を何度も何度も繰り返す可能性が非常に高いです。

(あなたはそれがオーバーするのを待っている会議に座っているとき、あなたは時計をチェックしておく方法などの種類 - と、それは常に同じ時間だ...)とにかく

、あなたがsrand関数を呼び出します(X)(Xがどんなものであれ)、それからごくわずかな命令でsrand(X)をもう一度呼びます。だから、あなたは乱数の同じシーケンスを取得し、最初のものだけを使用しています!

srand()をmainから電話した場合は問題ありません。 がsrand()を全く呼び出さなかった場合は、でも問題ありません。しかし、そのままでは、コンストラクト関数の乱数として常に srand(X)[0]を取得します。