rand() 在多个函数调用中是一致的

rand() is consistent across multiple function calls

当我尝试从函数调用中生成 2 个随机数时,我得到了重复的结果。

但是,rand() 函数在循环或其他情况下工作正常,前提是它们在函数调用之外。

我猜是因为系统时间的缘故,那个程序很小。但我不知道如何改变种子。

#include <stdio.h>
#include <ctype.h>
#include <string.h>

int test1(){

    int randX, randY;
    int range = 5;

    srand( time(NULL) );

    randX = (rand() % range) + 1; 

    randY = (rand() % 15   ) + 1;
    printf("X:%d  Y:%d\n", randX, randY);
}

int main(){

    test1();
    test1();
    test1();
    test1();
    test1();
}

根据 C11 标准文档,第 7.22.2.2 章,srand() 函数,

The srand() function uses the argument as a seed for a new sequence of pseudo-random numbers to be returned by subsequent calls to rand(). If srand() is then called with the same seed value, the sequence of pseudo-random numbers shall be repeated.

所以,您的代码的问题是您在 test1() 函数内调用 srand( time(NULL) );。实际上,您每次调用 test() 函数时都在为伪随机数生成器播种。现在,time(NULL) 将 return 整整一秒的相同值,即它具有 1 秒的时间粒度。因此,在该粒度周期 (1 秒)内连续调用 test() 函数 将导致

  • PRNG 将重新播种,具有相同
  • 连续调用 rand() 将产生相同的一组 随机 数字。

解决方案:您只需要从 main() 调用 srand( time(NULL) ); 一次。

也就是说,还有两件重要的事情要提,

  1. 您缺少所需的头文件。对于 rand()srand() 你需要 stdlib.h,对于 time() 包括 time.h.

  2. 您的 int test1() 函数被声明为具有 int 类型的 return 值,而您的函数没有任何 return 语句。如果调用者不使用 returned 值是可以接受的,但如果使用 returned 值,它将调用 undefined behavior。所以最好考虑在 test() 中添加一个 return 值或将 return 类型更改为 void.

旁注:

  1. main() 的推荐签名是 int main(void)(在本例中)。
  2. 添加显式 return 值被认为是一种好的做法,但在 main() 的情况下不是强制性的。

是因为你打电话

srand( time(NULL) );

每次使用该功能。它的粒度是一秒,所以如果你在很短的时间间隔内调用它两次,你将使用相同的值为随机数生成器播种 - 除非时钟恰好在 之间 两个电话。

您应该在程序开始时调用 srand() 一次