Oi, Pedro! Tudo bem?
O comportamento “estranho” do primeiro rand()
vem do fato de você semear com time(0)
, que tem resolução de 1 segundo. O primeiro valor gerado após srand(seed)
é determinístico e muito correlacionado com o seed; como entre execuções o seed muda de +1 (próximo segundo), o primeiro rand()
tende a variar pouco e de forma previsível. Já o segundo rand()
(e os subsequentes) avançam o estado do gerador e diluem essa correlação, parecendo mais “randômicos”.
Faça assim para evitar o problema:
- Semeie uma única vez por execução e nunca antes de cada número.
- Descarte alguns valores iniciais (warm-up) após
srand(...)
. - Se quiser melhorar a entropia do seed, combine
time(0)
com PID ou algum contador; e, quando possível, prefira um gerador melhor que rand()
.
Veja este exemplo:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#ifdef _WIN32
#include <process.h> // _getpid
#define GETPID _getpid
#else
#include <unistd.h> // getpid
#define GETPID getpid
#endif
int main(void) {
// 1) semente única por execução, misturando segundos com PID para variar entre execuções no mesmo segundo
unsigned int seed = (unsigned int)time(NULL) ^ (unsigned int)GETPID();
srand(seed);
// 2) warm-up: descarta os primeiros valores que são mais correlacionados com a semente
for (int k = 0; k < 8; ++k) (void)rand();
// 3) use rand normalmente
int a = rand();
int b = rand();
int c = rand();
int d = rand();
printf("seed=%u\\n", seed);
printf("%d %d %d %d\\n", a, b, c, d);
return 0;
}
Pontos importantes:
- Não chame
srand(...)
mais de uma vez no programa (semeie só no início). - Se rodar o binário várias vezes dentro do mesmo segundo,
time(0)
sozinho pode gerar valores iguais; a mistura com PID ajuda. - Para aplicações sérias, troque
rand()
por um gerador melhor (ex.: PCG, arc4random()
em sistemas BSD/macOS, getrandom()
//dev/urandom
em Linux, BCryptGenRandom
/rand_s
no Windows). Para o curso, o warm-up já resolve a percepção de “incrementos pequenos”.
Fico à disposição. Abraços e bons estudos!
Caso este post tenha lhe ajudado, por favor, marcar como solucionado ✓.