C语言随机数生成:rand和srand函数

MoyiTech
2022-10-21 / 0 评论 / 44 阅读 / 正在检测是否收录...

l9iekyf5.png

问题发现

在C语言中随机数通常用库文件stdlib.h中的rand函数产生
rand函数生成的伪随机数是根据种子产生的
在没有使用srand函数置入种子之前,每次程序运行时都会遍历同一张 随机数表

示例程序
#include<stdio.h>
#include<stdlib.h>

int main(){
    int a;
    int i;
    for(i=0;i<10;i++){
        a = rand();
        printf("%d\n", a);
    }
    
    return 0;
}

输出如下:

41
18467
6334
26500
19169
15724
11478
29358
26962
24464

--------------------------------
Process exited after 0.1282 seconds with return value 0
请按任意键继续. . .

问题分析

不难发现,每次运行程序所使用的随机数表都是一样的(随机数表的概念在高中数学课本里提到过),这样的随机数表是调用一个默认的种子生成的,这个种子一般是一个默认值,所以每次运行程序都会生成一串与上一次运行相同的随机数。
所以,要实现真正意义上的伪随机,在使用rand函数之前,要使用srand函数置入一个种子对默认种子进行一个“随机”的改变,也就生成了一张随机数表
这里我们就用到了srand函数,这个函数可以通过输入一个参数——种子 生成一张随机数表,那么srand函数这个参数应该如何进行“随机”呢?

时间戳

这里就需要用到库文件time.h中的time函数,并给其传一个参数0或NULL

示例程序
#include<stdio.h>
#include<time.h>

int main(){
    printf("%d", (unsigned int)time(NULL));
    return 0;
}

输出如下

1666349455
--------------------------------
Process exited after 0.01108 seconds with return value 0
请按任意键继续. . .

可以看到,程序输出了一串数字,这串数字叫做时间戳

时间戳是指格林威治时间1970年01月01日00时00分00秒(北京时间1970年01月01日08时00分00秒)起至现在的总秒数。

我们在运行程序时的时间不是固定的,所以,我们只需要在程序运行开始时将时间戳这个种子作为参数传递给srand函数用于生成随机数表即可实现一个伪随机功能

示例程序
#include<stdio.h>
#include<stdlib.h>
#include<time.h>

int main(){
    srand((unsigned int)time(NULL));
    int i;
    for(i=0;i<10;i++){
        printf("%d\n", rand()%100+10);
    }
    return 0;
}

输出如下

77
35
14
33
32
28
10
28
105
49

--------------------------------
Process exited after 0.01058 seconds with return value 0
请按任意键继续. . .

通过多次测试可以发现,每次都生成的数列都是不同的,达到了我们的目的。

应用

我们在生成随机数时通常需要一个指定的范围,在上文输出随机数的结果中不难发现随机数都是在10~110之间的数字。具体做法就是在调用rand函数中进行取模操作,即限制生成随机数的跨度,例如%100,跨度就是100(0~99)。当然了,我们需要的随机数并不都是从0开始的,这就需要在取模后加上一个常数作为随机数的起点,例如%100+10,就表示10~109(两边取等)。

补充

由于srand函数是通过传入的参数作为种子生成的随机数表,所以只需在程序运行开始时生成一次就好,如果将srand函数放在了for/while循环中,将可能因为循环时间短导致每次传入的时间戳参数相同,从而生成了同一张随机数表,而rand函数又从随机数表的开头开始遍历,这就导致了每次循环生成的随机数相同。

5

评论 (0)

取消