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

C語言隨機數生成:rand() 與 srand() 完整使用指南

     編輯:關於C語言

C 標準庫隨機數函數 rand() 與 srand() 深度解析

C 語言通過 <stdlib.h> 提供偽隨機數生成接口。掌握其正確用法,是避免「每次運行結果相同」等常見問題的關鍵。

一、函數原型與核心常量

#include <stdlib.h>
int rand(void);           // 返回 0 ~ RAND_MAX 間的偽隨機數
void srand(unsigned int seed); // 設置隨機種子
#define RAND_MAX 2147483647   // 最大值(32 位有符號整數最大值)

二、核心機制:線性同餘生成器 (LCG)

  • 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)) 能均勻分布,避免取模偏差。

四、常見錯誤與最佳實踐

五、進階替代方案

  • C11 <random.h>:提供 mt19937 等高質量引擎,支持多種分布。
  • POSIX drand48()/erand48():48 位狀態,線程安全版本 erand48_r()。
  • 加密級隨機:Linux /dev/urandom、Windows BCryptGenRandom、OpenSSL RAND_bytes()。

六、種子選擇建議

  1. 一般應用:time(NULL) + getpid() 組合,降低同秒啟動碰撞。
  2. 測試需重現:固定種子 srand(12345)。
  3. 高安全需求:讀取 /dev/urandom 或調用系統 CSPRNG。

正確使用 srand() 初始化種子、採用浮點映射而非取模、注意線程安全,即可在 C 中獲得質量可接受的偽隨機序列。關鍵任務請改用現代隨機數庫或系統 CSPRNG。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
錯誤做法問題正確做法
只調用 rand() 不調用 srand()每次運行序列相同程序啟動時調用一次 srand(time(NULL))
頻繁調用 srand(time(NULL))同一秒內種子相同,序列重複全程僅初始化一次種子
用 rand() % N 取模低位隨機性差,分布不均使用浮點映射或拒絕採樣
多線程直接共享 rand()數據競爭,序列破壞用 rand_r() 或線程局部生成器