C srand如何与rand功能相关?

C srand如何与rand功能相关?,c,random,srand,C,Random,Srand,我知道,如果不更改种子编号,每次运行rand()函数时都会生成相同的编号。这就是srand()的用武之地。时间总是在变化,所以我知道应该将时间(null)参数传递给srand。我的问题与下面的代码来自一个教程网站 int main() { int i, n=5; time_t t; /* Intializes random number generator */ srand((unsigned) time(&t)); /* Print 5 ra

我知道,如果不更改种子编号,每次运行rand()函数时都会生成相同的编号。这就是srand()的用武之地。时间总是在变化,所以我知道应该将时间(null)参数传递给srand。我的问题与下面的代码来自一个教程网站

int main()
{
    int i, n=5;
    time_t t;

    /* Intializes random number generator */
    srand((unsigned) time(&t));

    /* Print 5 random numbers from 0 to 50 */
    for( i = 0 ; i < n ; i++ ) {
        printf("%d\n", rand() % 50);
    }

    return(0);
}
还有兰德

printf("%d\n", rand() % 50);
兰德和srand之间的联系在哪里?我的意思或期望是,我假设rand()将从srand()获取一些参数,这样它就知道每次生成不同的数字。我假设它看起来像rand(srand(time(null))

这就像初始化一个变量而不使用它一样。srand正在初始化,但我看不到它正在被使用

兰德生成不同的数字是因为在兰德之前先调用了srand吗?

srand()
设置种子,兰德使用种子生成“随机”数字(引号中,因为它们通常是伪随机的)。如果您在第一次调用
rand
之前没有调用
srand
,就好像您调用了
srand(1)
将种子设置为1一样

许多代码使用当前时间作为种子,以便使每个程序运行时使用不同的随机数序列,但在调试期间,为了重复性的目的,您始终可以将其更改为类似于
srand(42)
。以及对
time()的调用
实际上不需要变量来放置时间,您只需传递NULL:

srand (time (NULL));
整个过程可以在一个单独的文件中实现,例如标准(
ISO C99 7.20.2.2 srand函数
)中给出的示例


next
是文件顶部的一个静态变量,这意味着它对文件外部的所有内容都不可见,但对文件内部的所有内容都可见(有点局部全局)。这是
srand()
rand()之间的通信方法

随机数种子是一个全局静态变量。
rand
srand
都可以访问它。

你看不到链接,因为(幸运的是!)设计
rand()的人
决定保留该实现细节,就像你看不到stdio的
文件中的内容一样;缺点是他们决定将该状态作为全局(但隐藏)变量,而不是生成器的参数

与不推荐使用的
rand_r()
:状态是一个无符号整数(假定为>=32位),这意味着即使禁止使用任何状态大于该值的更好的生成器,因为没有空间存储它

相反,通过隐藏内部状态,可以自由选择任何最有效的算法(速度、周期等),并在幕后使用它,只要您保证在不初始化的情况下调用rand与在seed==1的情况下调用srand相同

Paxdiablo向您展示了C标准中的示例;请参见eg,以获取使用不同生成器的示例,您可以将其隐藏在rand/srand后面

更清楚的是:如果
rand\u r
设计得当,就会有一个不透明类型,比如
rand\u t
(可以是整数、结构、数组等),你可以将其传递给
rand\u r
和一些形位的
sr
,如中所示

rand_t state;
srand_r(&state, 1);
n = rand_r(&state);

rand函数与此完全相同,只是只有一个
状态
变量。

rand提供一个伪随机数字序列

该数字由一个算法生成,该算法每次调用时都返回一个显然不相关的数字序列。该算法使用种子生成序列,该序列应使用函数srand初始化为某个不同的值

srand在每次调用时设置指向列表中某个位置的指针,您将进入该位置。如果您不在每次尝试时调用它或给它一个固定种子,它将为您提供相同的序列。许多人建议将当前秒作为种子。但如果您尝试在同一秒内运行代码两次,它将为您提供相同的序列


对于srand调用中使用的每个不同种子值,伪随机数生成器可以在命令行的后续rand调用中生成不同的连续结果,您可以通过键入
man 3 rand
man 3 srand
查看这些函数的文档ng更像是这两个函数的实现。这里有一个问题-标准是如何在
rand()中实现大量数字的
函数?它背后的逻辑是什么?我在所有方面都同意你的观点。但我认为OP只是想知道如果
srand
没有返回你传递给
rand
作为参数的东西,那么
rand
如何知道种子是什么。即使我们没有(不应该!)知道有多少个状态位或生成随机数的精确算法,事实上,状态是必需的,它的生命周期超过了函数调用的生命周期,并且它可以被两个函数访问,这是作为种子随机数生成器的不可避免的结果-没有任何抽象在某处不需要静态变量。
// RAND_MAX assumed to be 32767.
static unsigned long int next = 1;
void srand(unsigned int seed) { next = seed; }
int rand(void) {
    next = next * 1103515245 + 12345;
    return (unsigned int)(next/65536) % 32768;
}
rand_t state;
srand_r(&state, 1);
n = rand_r(&state);