首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C語言 rand() 與 srand() 偽隨機數完全指南:種子機制、範圍控制與浮點擴展

     編輯:關於C語言

rand() / srand() 是 C 標準庫提供的偽隨機數生成器(PRNG)。理解其確定性序列本質與種子機制,是正確使用的關鍵。本文系統整理調用規則、常見誤區、範圍映射公式與浮點擴展技巧。

兩大核心函數

函數原型說明
rand()int rand(void)返回 [0, RAND_MAX] 間偽隨機整數,RAND_MAX ≥ 32767 (0x7FFF)
srand()void srand(unsigned seed)設定種子,初始化內部狀態。同種子 → 同序列。

隱性調用規則(關鍵)

  1. 首次調用 rand() 前若未調用 srand(),隱性執行 srand(1)。
  2. 若調用過 srand(seed),後續 rand() 依該種子產生確定序列。

三大使用模式對比

模式一:不調用 srand() / srand(1) → 固定序列

for (int i=0; i<10; i++) printf("%d ", rand()%6);

每次運行輸出完全相同:5 5 4 4 5 4 0 0 4 2。適合除錯、測試、可重現實驗。

模式二:固定種子 srand(6) → 另一固定序列

srand(6);
for (int i=0; i<10; i++) printf("%d ", rand()%6);

輸出:4 1 5 1 4 3 4 4 2 2。同樣可重現,但序列不同。

模式三:時間種子 srand(time(0)) → 每次不同(生產環境標準)

#include <stdlib.h>
#include <time.h>

srand((unsigned)time(0));  // 秒級時間戳作種子
for (int i=0; i<10; i++) printf("%d ", rand()%6);

每秒啟動程式種子不同 → 序列不同。注意:同一秒內多次啟動種子相同,高頻場景需結合 getpid()、clock() 或高精度計時器。

範圍映射通用公式

// 產生 [a, b) 區間整數(含 a,不含 b)
int r = (rand() % (b - a)) + a;

// 簡寫:[0, n)
int r = rand() % n;

原理: 取模將 0~RAND_MAX 映射至 0~n-1。若 RAND_MAX+1 不能被 n 整除,分布略有偏差(對大多數應用可忽略)。

偽隨機浮點數生成

// [0.0, 1.0)
double r = rand() / (double)RAND_MAX;

// [0.0, 10.0)
double r = rand() / (double)(RAND_MAX / 10.0);

// 通用 [min, max)
double r = min + (max - min) * rand() / (double)RAND_MAX;

關鍵:除以 RAND_MAX(轉 double),而非取模。取模僅適用整數均勻分布。

進階:更好的隨機數(C11 / POSIX)

需求推薦方案
密碼學安全/dev/urandom、getrandom()、arc4random()
高品質統計特性C11 random.h、Mersenne Twister (mt19937)、PCG
執行緒安全rand_r(&seed) (POSIX)、C11 thrd_local 狀態
可重現並行Jump-ahead / 分塊種子策略

總結口訣

  1. 生產代碼必配 time(0) 種子。
  2. 整數用取模,浮點用除法。
  3. 同種子 = 同序列,利用此特性做測試回放。
  4. 安全/高並發/高品質場景 棄用 rand(),改用現代 PRNG。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved