程式設計常需產生隨機數,但電腦本身無法產生真正的隨機數,需透過「隨機種子」配合演算法產生偽隨機序列。若僅需少量隨機數或間隔較長,直接用時間戳當隨機數也可;但連續大量產生時,專門的隨機函數能保證序列符合均勻分布,避免「領導想開幾就開幾」的高重複率問題。
void srand(unsigned int seed);
seed 為無號整數,慣用 time(NULL) 取得秒級時間戳,需包含 <time.h>。
回傳 0 到 RAND_MAX(0x7fff,32767)間的 short 整數。需更大範圍時,可組合多個 rand() 結果運算。
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int main(void) {
int i, r;
srand((unsigned)time(NULL)); // 僅呼叫一次
for (i = 0; i < 10; i++) {
r = rand() % 10; // 0~9
printf("%3d\n", r);
}
return 0;
}
srand 參數產生的 rand 序列完全一致,可用於除錯重現。time(NULL) 精度只到秒,同一秒內多次呼叫種子相同,導致隨機數重複。rand 從頭開始產生。#include <stdlib.h>
#include <stdio.h>
#include <time.h>
int foo() {
int r;
srand((unsigned)time(NULL)); // 錯誤:每次呼叫都重設種子
r = rand() % 100;
return r;
}
int main(void) {
int i, r;
srand((unsigned)time(NULL));
for (i = 0; i < 10; i++) {
r = rand() % 100;
printf("%3d", r);
}
printf("\n");
for (i = 0; i < 10; i++) {
printf("%3d", foo()); // 全部輸出相同數值
}
printf("\n");
return 0;
}
輸出結果:
76 69 10 95 37 85 25 99 4 33 76 76 76 76 76 76 76 76 76 76 ← 全部相同,因 foo() 內重複 srand
srand(time(NULL))。<random> 或平台專用 API(如 CryptGenRandom、/dev/urandom)。rand 非執行緒安全,建議使用 rand_r 或 C++11 引擎。