我知道rand()函数会生成相同的编号,如果不更改种子编号,则每次运行它时都会生成相同的编号。srand()就是在这里出现的。时间总是在变化,所以我知道您应该将时间(空)参数传递给srand。我的问题是关于一个教程站点下面的代码。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| 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
", rand() % 50);
}
return(0);
} |
我看不到SRAND的链接
号
还有兰德。
兰德和SRAND之间的联系在哪里?我的意思是或期望是,我假设rand()将从srand()获得一些参数,这样它就知道每次生成不同的数字。我假设它看起来像rand(srand(time(null));
就像初始化一个变量而不使用它。srand正在初始化,但我看不到它正在使用。
兰德公司是否会产生不同的数字,因为SRAND在兰德公司之前被称为第一个?
- 在命令行中,您可以通过键入man 3 rand和man 3 srand来查看这些函数的文档。
随机数种子是一个全局静态变量。rand和srand都可以访问它。
srand()设置rand用来生成"随机"数的种子(在引号中,因为它们通常是伪随机的)。如果你在第一次打电话给rand之前没有打电话给srand,就好像你打电话给srand(1)把种子设为1。
许多代码使用当前时间作为种子,以便使每个程序运行时使用不同的随机数序列,但为了重复性的目的,您可以在调试期间将其更改为类似于srand(42)的序列。对time()的调用实际上不需要一个变量来放置时间,您只需传递NULL即可:
整个过程可以在一个单独的文件中实现,类似于标准(ISO C99 7.20.2.2 The srand function中给出的示例)。
1 2 3 4 5 6 7
| // 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;
} |
号
next是文件顶部的静态变量,这意味着它对文件外部的所有内容都不可见,但对文件内部的所有内容都可见(类似于局部全局)。这就是srand()和rand()之间的通信方式。
- 我认为OP所要求的更像是这两个函数的实现。
- 这里有一个问题——标准是如何到达rand()函数内部的大量数字的?它背后的逻辑是什么?
你看不到链接,因为(幸运的是!)设计rand()的人决定保留实现细节,就像你看不到FILE中来自stdio的内容一样;缺点是他们决定使该状态成为全局(但隐藏)变量,而不是生成器的参数。
与不推荐使用的rand_r()相反:状态是无符号整数(假定大于等于32位),这意味着即使是禁止使用状态大于该值的任何更好的生成器,也只是因为没有存储空间!
相反,通过隐藏内部状态,您可以自由选择任何最有效的算法(速度、周期等),并在幕后使用它,只要您保证在不初始化的情况下调用rand与在seed==1的情况下调用srand相同。
paxdiablo向您展示了C标准中的示例;请参见http://en.wikipedia.org/wiki/multiply-with-carry,以获取使用可以隐藏在rand/srand后面的不同生成器的示例。
更清楚一点:如果rand_r设计得当,就会有一个不透明的类型,比如rand_t(可以是一个整数、一个结构、一个数组,…),你可以把它传递给rand_r和一些下位的srand_r,如
1 2 3
| rand_t state;
srand_r(&state, 1);
n = rand_r(&state); |
rand函数与此完全相同,只是只有一个state变量。
- 我同意你的观点。但我想欧普只是想知道,如果srand不返回你作为参数传入rand的东西,rand如何知道种子是什么。即使我们没有(不应该!)知道有多少个状态位,或者生成随机数的精确算法,需要状态的事实,它的寿命超过了函数调用的寿命,并且两个函数都可以访问它,这是作为种子随机数生成器的不可避免的后果-没有抽象不需要静态变量。
兰德给你一个伪随机的数字序列。
这个数字是由一个算法生成的,该算法每次调用它时都返回一个明显不相关的数字序列。该算法使用一个种子来生成序列,该序列应使用函数srand初始化为一些独特的值。
srand在每次调用时都会将指针设置到您要进入的列表中的某个位置。如果你不每次尝试都调用它,或者给它一个固定种子,它会给你相同的序列。很多人建议把当前的第二个作为种子。但是,如果您尝试在同一秒中运行代码两次,它将为您提供相同的顺序。
对于调用srand时使用的每个不同的seed值,可以期望伪随机数生成器在随后调用rand时生成不同的结果序列,以供进一步解释。