Come si relaziona srand alla funzione rand?

Capisco che la funzione rand () genera lo stesso numero (s) ogni lo si esegue se non si modifica il numero di seme. È qui che entra in srand (). Il tempo cambia sempre, quindi so che dovresti passare il parametro time (null) a srand. La mia domanda è con il codice qui sotto da un sito tutorial.

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

Non vedo alcun collegamento dal srand

 ((unsigned) time(&t)); 

e rand.

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

Dov’è la connessione tra rand e srand? Ciò che intendo o mi aspetto è che presumo che rand () ottenga alcuni parametri da srand () in modo che sappia generare numeri diversi ogni volta. Presumo che assomiglierebbe a rand (srand (time (null));

È come inizializzare una variabile senza usarla per me. srand è in fase di inizializzazione, ma non vedo che venga utilizzato.

    Rand genera numeri diversi perché srand viene chiamato prima di rand?

    Il numero casuale di sementi è una variabile statica globale. rand e srand hanno entrambi accesso.

    srand() imposta il seme che viene usato da rand per generare numeri “casuali” (tra virgolette perché sono generalmente pseudo-casuali). Se non chiami srand prima della tua prima chiamata a rand , è come se avessi chiamato srand(1) per impostare il seme su uno.

    Un sacco di codice usa l’ora corrente come seme per fare in modo che ogni programma usi una sequenza diversa di numeri casuali ma è sempre ansible cambiarlo in qualcosa come srand(42) durante il debug, ai fini della ripetibilità. E il call to time() realtà non ha bisogno di una variabile per inserire l’ora, puoi semplicemente passare NULL:

     srand (time (NULL)); 

    L’intera cosa potrebbe essere implementata in un singolo file con qualcosa di simile al seguente, l’esempio fornito nello standard ( 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; } 

    Il fatto che la next sia una variabile statica nella parte superiore del file significa che è invisibile a tutto ciò che è al di fuori del file, ma visibile a tutto ciò che è all’interno (una sorta di globale localizzato). Questo è il metodo di comunicazione tra srand() e rand() .

    Non vedi un collegamento perché (per fortuna!) Chiunque abbia progettato rand() deciso di mantenere un dettaglio di implementazione, nello stesso modo in cui non si vede cosa c’è all’interno di un FILE da stdio; il lato negativo è che hanno deciso di rendere questo stato una variabile globale (ma nascosta) piuttosto che un parametro per il generatore.

    Contrariamente al deprecato rand_r() : lo stato è un intero senza segno (si presume che sia> = 32 bit), il che significa che anche è vietato usare un generatore migliore il cui stato è maggiore di quello, semplicemente perché non c’è spazio per memorizzalo!

    Tenendo nascosto lo stato interno, si è liberi di scegliere qualsiasi algoritmo che funzioni meglio (velocità, periodo, …) e di utilizzarlo dietro le quinte, a patto che si garantisca che chiamare rand senza inizializzazione sia lo stesso di chiamare srand con seme == 1.

    Paxdiablo ti ha mostrato l’esempio dello standard C; vedi ad es. http://en.wikipedia.org/wiki/Multiply-with-carry per un esempio usando un generatore diverso che potresti hide dietro rand / srand.

    Giusto per essere extra-extra chiaro: se rand_r fosse stato progettato correttamente, ci sarebbe stato un tipo opaco, ad esempio rand_t (che potrebbe essere un numero intero, una struttura, un array, …), che rand_r a rand_r e ad alcuni ipotetico srand_r , come in

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

    La funzione rand è esattamente come questa, tranne che c’è solo una variabile di state .

    rand ti dà una sequenza pseudo casuale di numeri.

    Questo numero è generato da un algoritmo che restituisce una sequenza di numeri apparentemente non correlati ogni volta che viene chiamato. Questo algoritmo utilizza un seme per generare la serie, che deve essere inizializzato con un valore distintivo utilizzando la funzione srand.

    srand su ogni chiamata imposta il puntatore su un punto della lista in cui stai entrando. Se non lo chiami per ogni tentativo o gli dai un seme fisso, ti darà la stessa sequenza. Così molti suggeriscono di dare il secondo attuale come seme. Ma se provi a eseguire il codice nello stesso secondo due volte, ti darà la stessa sequenza.

    Per ogni diverso valore di seme usato in una chiamata a smalto, ci si può aspettare che il generatore di numeri pseudo casuali generi una diversa successione di risultati nelle successive chiamate a rand per ulteriori spiegazioni