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

VC++ 中 srand 與 rand 隨機函數深度解析與常見陷阱

     編輯:關於C語言

程式設計常需產生隨機數,但電腦本身無法產生真正的隨機數,需透過「隨機種子」配合演算法產生偽隨機序列。若僅需少量隨機數或間隔較長,直接用時間戳當隨機數也可;但連續大量產生時,專門的隨機函數能保證序列符合均勻分布,避免「領導想開幾就開幾」的高重複率問題。

一、核心函數說明

1. srand — 設定隨機種子

void srand(unsigned int seed);

seed 為無號整數,慣用 time(NULL) 取得秒級時間戳,需包含 <time.h>。

2. rand — 產生偽隨機數

回傳 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;
}

三、關鍵注意事項(避坑指南)

  1. 種子固定 → 序列固定:相同 srand 參數產生的 rand 序列完全一致,可用於除錯重現。
  2. 快速連續呼叫 srand 會產生相同序列:time(NULL) 精度只到秒,同一秒內多次呼叫種子相同,導致隨機數重複。
  3. 每次 srand 會重置序列:設定種子後,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))。
  • 需要高品質隨機數(密碼學、科學計算)請改用 C++11 <random> 或平台專用 API(如 CryptGenRandom、/dev/urandom)。
  • 多執行緒環境下 rand 非執行緒安全,建議使用 rand_r 或 C++11 引擎。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved