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

C 語言偽隨機數生成完全指南:rand/srand 原理、種子設定與範圍控制

     編輯:關於C語言

偽隨機數的本質:決定性演算法

C 標準庫的 rand() 產生的並非真正隨機數,而是偽隨機數。它基於一個種子,透過特定遞推公式生成數列。當數列足長時,統計分布近似常態分布。電腦啟動後預設種子固定,若不干預,每次執行產生的序列完全相同。

核心函數:srand() 設種子,rand() 取值

  • void srand(unsigned int seed):設定種子。常用 time(NULL) 取當前時間作種子,確保每次執行序列不同。
  • int rand(void):返回 0 到 RAND_MAX(至少 32767)間的偽隨機整數。

標準用法範例

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

int main(void) {
    srand((unsigned)time(NULL)); // 初始化種子

    // 1. 產生 0~RAND_MAX 間的隨機數
    for (int i = 0; i < 10; ++i)
        printf("%6d\n", rand());

    // 2. 產生指定範圍 [min, max] 的隨機整數
    int min = 0, max = 100;
    for (int i = 0; i < 10; ++i) {
        int val = min + (int)((double)rand() / (RAND_MAX + 1) * (max - min + 1));
        printf("%6d\n", val);
    }
    return 0;
}

常見範圍控制技巧與陷阱

需求推薦寫法說明
[0, 1] 浮點數rand() / (RAND_MAX + 1.0)避免整數除法截斷
[min, max] 整數min + rand() % (max - min + 1)簡單但分布略有偏差(RAND_MAX+1 不整除範圍大小時)
均勻分布整數拒絕採樣法丟棄超出範圍的值,嚴格均勻

進階:非標準函數 random()/randomize()

random(num) 直接返回 0 到 num-1,randomize() 自動以時間設種子。但它們非 ANSI C 標準,僅部分編譯器(如舊版 Turbo C、Borland C)支援,不可用於跨平台程式碼。請堅持使用標準 rand/srand。

產生不重複隨機序列:洗牌演算法

// Fisher-Yates 洗牌:產生 1~512 的隨機排列
int a[513];
for (int i = 1; i <= 512; ++i) a[i] = i;
for (int i = 512; i >= 1; --i)
    swap(&a[i], &a[rand() % i + 1]); // 注意 +1 避免索引 0

此法時空複雜度 O(N),適用於抽獎、洗牌等需不重複隨機序列的場景。

總結

  • 必須呼叫 srand() 設種子,推薦 srand((unsigned)time(NULL))。
  • rand() 返回 int,範圍 [0, RAND_MAX]。
  • 範圍映射首選浮點數縮放法(均勻)或模運算法(簡單)。
  • 不重複序列使用 Fisher-Yates 洗牌演算法。
  • 避免使用非標準 random()/randomize()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved