2016-03-25 29 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); 
} 

Yukarıdaki kod, amaçlandığı gibi üç farklı tam sayı üretir. Ancak, srandom ((imzasız) zaman (NULL)) sep_gen() işlevi kullanıldığında, oluşturulan tam sayılar üç kez aynıdır. (Aşağıdaki kodu) Neden srandom (time (NULL)) main() işlevi ve kullanıcı tanımlı bir işlevden farklı davranır?

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

Sorum

neden() işlevi srandom ana işlevi yerleştirildiğinde rasgele() fonksiyonu farklı sayılar üreten olmasıdır, ama ne zaman sep_gen() işlevi böylece yapmıyor?

+0

'srandom işlevi standart bir işlev değildir. – Olaf

+0

@Olaf: [Man sayfası] 'na göre POSIX.1-2001'in bir parçası (http://linux.die.net/man/3/srandom). Neden önemli olduğuna emin değilim. – ShadowRanger

+0

@ShadowRanger: Bakın [ask] ve ne [mcve]. Örneğin, uygun bir etiket var. POSIX, aksi takdirde metinde olmalıdır. – Olaf

cevap

2

değil bir kere program akışı başına, sep_gen denir her zaman reseed anlamına gelir. Ve time, çağlardan beri saniye geri döndü; Programınızın her ikisi de aynı saniyede üç kez sep_gen'u arayacaktır, bu nedenle her bir random çağrısından önce sabit bir başlangıç ​​noktasına yeniden gönderim yapıyorsunuz demektir. Temel olarak, bir kural olarak, bir program sadece rastgele bir kaynağını bir kez tohumlamak zorundadır, ya da herhangi bir nedenden dolayı yeniden beslenmesi gerekiyorsa, yeterince değişmeyen bir tohum kaynağı kullanmadığından emin olunması gerekir. Kendinizi tekrar etmeden yeniden çoğaltmak için gerçekten basit bir yaklaşım, srandom(time(NULL)^random()); gibi bir şey olurdu, bu nedenle jeneratörün mevcut durumu, time()'un yetersiz şekilde değişen harici tohum kaynağını bozar. Bu sadece bir oyuncak örneğidir (sürekli olarak time ile engellenmesi beklenen davranışlarda büyük değişiklikler yapmaz), daha karmaşık senaryolarda böyle bir şeyi nasıl yapabileceğinize dair bir not.

+0

Yeniden üretim yaklaşımını detaylandırır mısınız? 'Srandom (time (NULL)^random());' Çalış ?, ne yaptın? Beklediğiniz davranışta büyük değişiklikler yapamayacağınız zaman ne demek istediniz? Özür dilerim, yeni başlayan biriyim, bu yüzden o bölümü izlemedim. –

+0

@ArshithaBasavaraj: Mevcut akıştan bir değer almak için "rastgele" yi çağırıyor. f 'time' ile rasgele ve bitsel olarak özel veya.Bu yüzden tohumun, iki tohumluk "rastgelelik" kaynağı vardır, son tohumlamaya ne olursa olsun, ve o zamandan beri kaç kez rastgele çekilmiştir (bu durumda, her seferinde yeniden gönderilir), artı "zaman" çıktısı. Bitwise xor, iki değerin, birbirlerinin bitlerini yararlı bir şekilde bir araya getirdiği anlamına gelir. Davranışları pek değiştirmez çünkü çoğu zaman “rastgele” akım öngörülebilir olurdu; Programın başlatıldığı zamanı biliyorsanız, rastgele akışı yeniden oluşturabilirsiniz. – ShadowRanger

2

Bu, kodunuzun hızlı işlenmesinden kaynaklanmaktadır. Ne srandom, rasgele sayı üretecinin tohumunu sıfırlıyor. Bir fonksiyon içinde çağırırsanız, bir fonksiyon çağırdığınızda mevcut saat ile güncellenecektir. Hesaplamalar o kadar hızlıdır ki, her çağrıda aynı zaman alınır ve bu nedenle, belirli bir tohum için ilk sayı dizisi olarak aynı sayı üretilir. sep_gen bunu koyarak

+0

Sadece bir kez çağrılır, böylece tohum aynı değere sıfırlanmaz – greenshade

+0

0 ile ardışık tamsayılar dizisi başlatma olarak düşünün. Bir kez 0, 1, 2, 3 ve daha sonra alırsınız.Eğer her seferinde 0'a sıfırlarsanız 0, 0, 0 ... – greenshade

+0

alırsınız. Bu, ana fonksiyonda olduğunda nasıl değişir? (Üzgünüm, sorumu tekrar ettim) –

İlgili konular