程序员求职经验分享与学习资料整理平台

网站首页 > 文章精选 正文

C语言srand函数详解:随机数的「播种者」

balukai 2025-03-26 09:42:42 文章精选 11 ℃

核心定位

srand 是C语言中初始化随机数生成器的「播种者」,它通过设置随机种子,决定 rand 函数生成的随机数序列。就像种下一颗种子,决定了未来长出的植物(随机数)的模样!


函数原型与参数

void srand(unsigned int seed);
  • 入口参数
    seed:随机种子(unsigned int 类型)
    • 常用种子:time(NULL)(基于当前时间,确保每次运行结果不同)
    • 固定种子:若种子固定(如 srand(123)),rand 生成的序列也固定
  • 返回参数:无(void 函数)

实战代码演示

场景1 初始化随机种子

#include 
#include 
#include 

int main() {
    //  播种随机种子(基于当前时间)
    srand(time(NULL));

    // 生成随机数
    for (int i = 0; i < 5; i++) {
        printf("随机数 %d:%d\n", i + 1, rand());
    }
    return 0;
}

输出示例

随机数 1:12345  
随机数 2:67890  
随机数 3:54321  
随机数 4:98765  
随机数 5:43210  

(每次运行结果不同)


场景2 固定种子(用于调试)

int main() {
    //  播种固定种子
    srand(123);

    // 生成随机数
    for (int i = 0; i < 5; i++) {
        printf("随机数 %d:%d\n", i + 1, rand());
    }
    return 0;
}

输出示例

随机数 1:128959393  
随机数 2:1692901013  
随机数 3:436085873  
随机数 4:748533525  
随机数 5:498507034  

(每次运行结果相同)


场景3 结合rand生成随机范围

// 生成 [min, max] 范围内的随机数
int rand_range(int min, int max) {
    return min + rand() % (max - min + 1);
}

int main() {
    srand(time(NULL));

    // 生成 1 到 6 之间的随机数(模拟骰子)
    int dice = rand_range(1, 6);
    printf("掷骰子结果:%d\n", dice);  // 输出:1 到 6 之间的随机数
    return 0;
}

四大致命陷阱

陷阱

后果

防御方案

未调用srand

每次运行结果相同

程序启动时调用 srand(time(NULL))

种子固定

随机性丧失

使用动态种子(如时间戳)

多次调用srand

随机性降低

仅在程序启动时调用一次

种子范围过小

随机性受限

使用高精度时间戳或随机设备


增强版随机种子初始化

使用高精度时间戳

#include 
#include 
#include 

int main() {
    //  使用高精度时间戳作为种子
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    srand(ts.tv_nsec);  // 使用纳秒部分

    // 生成随机数
    printf("随机数:%d\n", rand());
    return 0;
}

使用随机设备(Linux/Unix)

#include 
#include 

int main() {
    //  从随机设备读取种子
    FILE *urandom = fopen("/dev/urandom", "r");
    if (urandom) {
        unsigned int seed;
        fread(&seed, sizeof(seed), 1, urandom);
        fclose(urandom);
        srand(seed);
    } else {
        srand(time(NULL));  // 回退到时间戳
    }

    // 生成随机数
    printf("随机数:%d\n", rand());
    return 0;
}

对比srand与C++11随机数库

特性

srand

C++11随机数库

随机性质量

较低

种子管理

需手动初始化

自动管理

灵活性

仅支持整数种子

支持多种随机引擎

性能

略低


黄金法则

  1. 播种一次:仅在程序启动时调用一次 srand
  2. 动态种子:使用 time(NULL) 或高精度时间戳
  3. 固定种子调试:在调试时使用固定种子(如 srand(123))
  4. 高质量随机数:在需要高随机性时,使用C++11的

脑洞应用:随机迷宫生成

#include 
#include 
#include 

#define WIDTH 10
#define HEIGHT 10

void generate_maze(char maze[HEIGHT][WIDTH]) {
    srand(time(NULL));

    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            maze[y][x] = (rand() % 4 == 0) ? '#' : ' ';  // 25%的概率生成墙
        }
    }
}

int main() {
    char maze[HEIGHT][WIDTH];
    generate_maze(maze);

    // 打印迷宫
    for (int y = 0; y < HEIGHT; y++) {
        for (int x = 0; x < WIDTH; x++) {
            printf("%c", maze[y][x]);
        }
        printf("\n");
    }
    return 0;
}

输出示例

#   # #   
# #   # # 
  #     # 
#   # # # 
  # #   # 
#   # # # 
# #   # # 
  # #   # 
#   # # # 
# #   # # 

srand 如同一位播种者——种下不同的种子,收获不同的随机数序列。掌握它的特性后,让你的程序在随机世界中自由生长!

最近发表
标签列表