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

C語言隨機數生成:從舊式randomize()到現代srand()/rand()完全指南

     編輯:C 語言問答

直接回答

randomize() 和 random() 是 **Turbo C / Borland C** 等舊式編譯器的**非標準擴展函數**,**不屬於C標準庫**,現代編譯器(GCC、MSVC、Clang)均**不支持**。

標準C隨機數方案

函數頭文件作用標準
srand(seed)<stdlib.h>設置隨機數種子C89
rand()<stdlib.h>生成偽隨機數 [0, RAND_MAX]C89
time(NULL)<time.h>獲取當前時間戳作為種子C89

為什麼需要 srand()?

rand() 產生的是**偽隨機數序列**,由確定性算法生成。若不調用 srand() 設置種子,默認種子為 1,**每次程序運行產生的序列完全相同**。

標準用法模板

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

int main() {
    // 1. 設置種子:僅在程序啟動時調用一次!
    srand((unsigned int)time(NULL));
    
    // 2. 生成隨機數
    for (int i = 0; i < 10; i++) {
        printf("%d ", rand());
    }
    printf("\n");
    
    return 0;
}

常見範圍轉換技巧

需求公式示例:生成 1-100
整數 [0, N-1]rand() % Nrand() % 100 → 0-99
整數 [a, b]a + rand() % (b - a + 1)1 + rand() % 100 → 1-100
浮點數 [0.0, 1.0)(double)rand() / RAND_MAX(double)rand() / RAND_MAX
浮點數 [a, b)a + (b-a) * rand() / RAND_MAX1.0 + 99.0 * rand() / RAND_MAX

C-Free / Code::Blocks / Dev-C++ 配置提示

  1. 確保包含 <stdlib.h> 和 <time.h>
  2. 編譯器設置為 C99 或更高標準
  3. 若報錯 time 未聲明,檢查頭文件拼寫
  4. 部分舊教材用 randomize(),直接替換為 srand(time(NULL))

進階:更好的隨機數質量

C11 標準 <random.h> (部分編譯器支持)

// 現代C++風格在C中不可用,但可手工實現更好算法
// 例如:Mersenne Twister (MT19937) 移植版

密碼學安全隨機數

  • Linux: getrandom()、/dev/urandom
  • Windows: BCryptGenRandom()、CryptGenRandom()
  • 跨平台庫: libsodium 的 randombytes_buf()

常見錯誤避坑

❌ 錯誤示範

// 錯誤1:循環中重複調用 srand()
for(i=0; i<10; i++) {
    srand(time(NULL));  // 同一秒內種子相同!
    printf("%d ", rand());
}

// 錯誤2:未包含頭文件
rand();  // 隱式聲明警告,行為未定義

// 錯誤3:期望真隨機
// rand() 是偽隨機,不可用於加密、安全關鍵場景

歷史背景補充

  • randomize() 相當於 srand(time(NULL))
  • random(n) 相當於 rand() % n
  • Turbo C 2.0/3.0 (1990年代) 專用,現代教學不應再使用
  • 《C程序設計語言》(K&R) 從未包含這兩個函數

驗證程序:觀察種子影響

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

void test_seed(unsigned int seed) {
    srand(seed);
    printf("Seed %u: ", seed);
    for(int i=0; i<5; i++) printf("%d ", rand());
    printf("\n");
}

int main() {
    test_seed(1);    // 默認種子
    test_seed(42);   // 固定種子 → 固定序列
    test_seed(100);  // 另一固定種子
    // 實際應用中只用 time(NULL) 作為種子
    return 0;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved