C primer plus学习笔记 —— 15、随机数函数详解

文章目录

    • rand和srand函数
      • 函数原型
      • 生成任意随机数
      • 生成多个随机数问题
    • rand和srand实现

rand和srand函数

函数原型

#include 
int rand(void);
int a = rand() % 10;    //产生0~9的随机数,注意10会被整除
int a = rand() % 51 + 13;    //产生13~63的随机数

rand函数界限:stdlib.h头文件中有宏#define RAND_MAX 0x7fff
rand产生一个0-0x7fff的随机数,即最大是32767的一个数

#include 
#include 
int main(){
    int a = rand();
    printf("%d\n",a); //196
    return 0;
}

实际上,rand() 函数产生的随机数是伪随机数,是根据一个数值按照某个公式推算出来的,这个数值我们称之为“种子”。如果我们不使用srand指定种子,那么这个种子值默认为1.

我们可以通过 srand() 函数来重新“播种”,这样种子就会发生改变。

#include 
#include 
int main(){
	srand(2);
    int a = rand();
    printf("%d\n",a); //128
    return 0;
}

生成任意随机数

因为我们的种子每次如果是固定值,那么我们最终生成的随机数每次启动程序还是相同的。
那么我们想每次运行程序都生成任意随机数,怎么办呢?
我们可以使用时间作为种子,这样每次启动程序都是任意随机数。

#include 
#include 
#include 
int main(){
    int a;
    srand((unsigned)time(NULL));
    a = rand() % 51 + 13;
    printf("%d\n",a);
    return 0;
}

生成多个随机数问题

有时候我们需要一组随机数(多个随机数),该怎么生成呢?

#include 
#include 
#include 
int main(void)
{
    srand(1);
    int num = rand() % 10;
    //srand(1);
    int num1 = rand() % 32;
    //srand(1);
    int num2 = rand() % 32;

    printf("random number %d, %d, %d !\n", num, num1, num2);
    
    return 0;
}

这个实例出现一个奇怪的现象,因为默认srand设置种子为1,那么我调用一次srand后面多次调用rand是否会生效呢。
对比发现,如果我仅设置一次srand多次调用rand 和 每次设置rand和srand相对应,得到的结果是不一样
所以先得出一个结论:每次使用rand函数如果想随机,前面都要调用一次srand生成随机数种子。这样才是想要的结果。
那么具体是为什么,我们来看rand和srand函数的具体实现

rand和srand实现

#include
#include

static unsigned long next = 1; //静态全局变量,作为种子

void my_srand(unsigned long seed)//通过传不同的参数更改种子值,一般传time(NULL)
{
    next = seed;
}

int my_rand(void)//将srand的种子值通过公式计算出结果作为随机值
{
    printf("next = %lu,  ", next);
    next = next * 1103515245 + 12345;
    return((unsigned)(next/65536) % 32768);
}

int main()
{
    my_srand(1);
    int i;
    for (i = 0; i < 10; i++) {
        printf("rand: %lu\n",my_rand()%10);
    }
    return 0;
}
/*
next = 1,  rand: 8
next = 1103527590,  rand: 8
next = 1217759518843121895,  rand: 3
next = 15426401326682203284,  rand: 5
next = 14214738562022873917,  rand: 1
next = 370094621659488050,  rand: 7
next = 9366438228929508483,  rand: 0
next = 11936857473893447168,  rand: 9
next = 9715927332899499577,  rand: 2
next = 8164741156552621182,  rand: 6
*/

从上面代码很容易看出,实际上这个随机种子是一个静态变量,默认是1,但是他在调用rand的时候是会被修改的。以为他是一个静态全局变量,而且他放在了头文件中
所以我们如果连续调用rand,那么下一次rand使用的seed值就并不是我们期望的了,也就是后面生成的值并不是使用种子1生成的
当然如果仅需要,因为这个seed值是unsigned所以会循环使用,也不会越界。

int main()
{
    my_srand(1);
    printf("rand: %lu\n",my_rand()%10);
    my_srand(1);
    printf("rand: %lu\n",my_rand()%10);
    my_srand(1);
    printf("rand: %lu\n",my_rand()%10);
    my_srand(1);
    printf("rand: %lu\n",my_rand()%10);
    return 0;
}

所以我们在每次调用rand时候如果要想保证可控需要设置一下种子srand。

你可能感兴趣的:(C语言学习笔记,c语言,学习,c++)