rand() 與 srand() 深度解析C 語言通過 <stdlib.h> 提供偽隨機數生成接口。掌握其正確用法,是避免「每次運行結果相同」等常見問題的關鍵。
#include <stdlib.h>
int rand(void); // 返回 0 ~ RAND_MAX 間的偽隨機數
void srand(unsigned int seed); // 設置隨機種子
#define RAND_MAX 2147483647 // 最大值(32 位有符號整數最大值)
rand() 內部維護一個狀態值(種子),每次調用通過線性同餘公式更新並返回新值。srand() 時,默認種子為 1,導致每次程序啟動產生相同序列。#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(void) {
// 1. 以當前時間作種子(秒級精度)
srand((unsigned int)time(NULL));
// 2. 生成 [1, 10] 範圍內的隨機整數
for (int i = 0; i < 10; ++i) {
int r = 1 + (int)(10.0 * rand() / (RAND_MAX + 1.0));
printf("%d ", r);
}
return 0;
}
關鍵點:
time(NULL) 返回秒級時間戳,每次運行種子不同。min + (int)(range * rand() / (RAND_MAX + 1.0)) 能均勻分布,避免取模偏差。| 錯誤做法 | 問題 | 正確做法 |
|---|---|---|
只調用 rand() 不調用 srand() | 每次運行序列相同 | 程序啟動時調用一次 srand(time(NULL)) |
頻繁調用 srand(time(NULL)) | 同一秒內種子相同,序列重複 | 全程僅初始化一次種子 |
用 rand() % N 取模 | 低位隨機性差,分布不均 | 使用浮點映射或拒絕採樣 |
多線程直接共享 rand() | 數據競爭,序列破壞 | 用 rand_r() 或線程局部生成器 |