前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C语言随机数生成:rand和srand函数

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

作者头像
MoyiTech
发布2023-02-27 14:52:06
2.1K0
发布2023-02-27 14:52:06
举报
文章被收录于专栏:科技日常科技日常
l9iekyf5.png
l9iekyf5.png

问题发现

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

示例程序
代码语言:javascript
复制
#include
#include

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

输出如下:

代码语言:javascript
复制
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

示例程序
代码语言:javascript
复制
#include
#include

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

输出如下

代码语言:javascript
复制
1666349455
--------------------------------
Process exited after 0.01108 seconds with return value 0
请按任意键继续. . .

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

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

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

示例程序
代码语言:javascript
复制
#include
#include
#include

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

输出如下

代码语言:javascript
复制
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函数又从随机数表的开头开始遍历,这就导致了每次循环生成的随机数相同。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 问题发现
  • 问题分析
    • 时间戳
    • 应用
    • 补充
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档