2014-01-22 130 views
15

我知道rand()函數會生成相同的數字(s),如果您不更改種子編號,則每個函數都會運行它。這就是srand()進來的地方。時間總是在變化,所以我知道你應該把時間(空)參數傳遞給srand。我的問題是從教程網站下面的代碼。srand與rand函數的關係如何?

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); 
} 

我看到從函數srand

((unsigned) time(&t)); 

和蘭德沒有任何聯繫。

printf("%d\n", rand() % 50); 

rand和srand之間的連接在哪裏?我的意思是或者期望的是我假設rand()會從srand()得到一些參數,所以它知道每次都會產生不同的數字。我相信它會看起來像蘭特(函數srand(時間(空));

這就像初始化的變量,而不使用它給我函數srand正在初始化,但我沒有看到它被用來

rand是否會生成不同的數字,因爲srand在rand之前先被調用?

+0

在命令行結果的不同演替,你可以看到通過輸入'man 3 rand'和'man 3 srand'來記錄這些功能。 – tlehman

回答

19

隨機數種子是一個全局靜態變量。 randsrand都有權訪問它。

13

srand()設置rand用於生成「隨機」數字的種子(在引號中,因爲它們通常是僞隨機的)在您第一次撥打電話rand之前撥打srand,就好像您撥打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()之間的通信方式。

+0

我想OP所要求的更像是這兩個功能的實現。 – WiSaGaN

+0

這裏有一個問題 - 標準如何達到'rand()'函數中的大數字?它背後的邏輯是什麼? – Gopi

4

你沒有看到鏈接,因爲(幸運的是)誰設計了rand()決定保留一個實現細節,就像你沒有看到stdio內的FILE裏面有什麼一樣;缺點是他們決定讓這個狀態成爲一個全局的(但隱藏的)變量而不是生成器的一個參數。

對比度即到棄用rand_r():所述狀態是無符號整數(假設爲> = 32位),這意味着,即使它禁止使用任何更好發生器,其狀態是大於,只是因爲有沒有空間來存儲它!

通過保持內部狀態隱藏,相反,一個人可以自由選擇最適合的算法(速度,週期......)並在幕後使用它,只要您保證沒有初始化的調用rand就是與調用種子== 1的srand相同。

Paxdiablo向你展示了C標準的例子;請參閱http://en.wikipedia.org/wiki/Multiply-with-carry,例如使用可以隱藏在rand/srand後面的不同發生器。

只是要特別清楚:如果rand_r的設計正確,將會有一個不透明的類型,比如rand_t(可能是一個整數,一個結構,一個數組...),您將傳遞給rand_r和一些hypotetical srand_r,如

rand_t state; 
srand_r(&state, 1); 
n = rand_r(&state); 

蘭特功能是完全一樣,不同的是隻有一個變量state

+0

我同意你的觀點。但我想OP只是想知道'rand'知道如果'srand'沒有返回你傳入'rand'作爲參數的東西時種子是什麼。即使我們不知道(不應​​該)知道有多少狀態存在或者產生隨機數的確切算法,但是狀態是需要的,它的生命週期超過了函數調用的時間,並且它可以被訪問兩個函數是一個種子隨機數生成器的不可避免的結果 - 沒有抽象,不需要靜態變量。 – sqykly

0

rand給你一個僞隨機數字序列。

該數字由算法生成,該算法每次調用時都會返回一系列明顯不相關的數字。該算法使用種子來生成序列,應該使用函數srand將其初始化爲一些獨特的值。

srand每次調用都會將指針指向列表中的某個位置,如果您沒有在每次嘗試時調用它或給它一個修復種子,它會給你相同的順序。所以很多人建議把當前的第二個作爲種子。但是如果你嘗試在同一秒內運行你的代碼兩次,它會給你同樣的順序。

對於在調用中使用函數srand每一個不同的種子值,僞隨機數生成器,可以預計產生的後續調用蘭特for further explanation