rand()如何在C中工作?

时间:2015-10-27 23:26:00

标签: c

我知道rand()生成一个随机数。我找到了this example

#include <stdio.h>
#include <stdlib.h>

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

   n = 5;

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

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

   return(0);
}

我知道这个问题可能听起来有些愚蠢,但任何人都可以解释一下上面的代码是如何工作的吗?

1 个答案:

答案 0 :(得分:5)

您应该知道获取有关C标准库的信息的最简单方法是在Linux / UNIX系统上使用手册页。

手册章3是您可以找到有关标准库的手册页。要获取rand的文档,请在shell提示符下键入man 3 rand

如果您没有方便的手册页,我只想引用这里的描述:

DESCRIPTION

   The  rand()  function returns a pseudo-random integer in the range 0 to
   RAND_MAX inclusive (i.e., the mathematical range [0, RAND_MAX]).

   The srand() function sets its argument as the seed for a  new  sequence
   of  pseudo-random  integers  to be returned by rand().  These sequences
   are repeatable by calling srand() with the same seed value.

   If no seed value is provided,  the  rand()  function  is  automatically
   seeded with a value of 1.

   The function rand() is not reentrant or thread-safe, since it uses hid‐
   den state that is modified on each call.  This might just be  the  seed
   value to be used by the next call, or it might be something more elabo‐
   rate.  In order to get reproducible behavior in a threaded application,
   this  state must be made explicit; this can be done using the reentrant
   function rand_r().

   Like rand(), rand_r() returns a  pseudo-random  integer  in  the  range
   [0, RAND_MAX].  The seedp argument is a pointer to an unsigned int that
   is used to store state between calls.  If rand_r() is called  with  the
   same  initial value for the integer pointed to by seedp, and that value
   is not modified between calls, then  the  same  pseudo-random  sequence
   will result.

   The  value pointed to by the seedp argument of rand_r() provides only a
   very small amount of state, so this function will be a weak pseudo-ran‐
   dom generator.  Try drand48_r(3) instead.

RETURN VALUE

   The rand() and rand_r() functions return a value between 0 and RAND_MAX
   (inclusive).  The srand() function returns no value.

如果你想知道代码本身是如何工作的,我可以为你分解:

#include <stdio.h>

包括标准I / O库。 (在这种情况下需要获得printf()的定义。)

#include <stdlib.h>

包含C标准库(适用于当前平台)。需要这样才能获得rand()srand()time()的定义。

int main()

定义函数main(),该函数将在以后作为已编译可执行文件的入口点进行查找。

{

定义main()

的范围
   int i, n;

在堆栈上为两个int变量in分配内存空间。

   time_t t;

在堆栈上为time_t结构分配内存空间,稍后将用于当前时间。

   n = 5;

int n初始化为值5。

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

首先调用time(),其参数是先前在堆栈上分配的time_t的内存地址。这将使用当前时间填充time_t。 (实际上只是表示为一个整数 - 自“epoch”以来的秒数 - 见man 2 time

接下来,使用该值调用srand()(在将其转换为unsigned int之后,这可能会避免编译器警告,但如果您知道sizeof(time_t) >= sizeof(int),则可能是安全的。)。在此处调用srand()将播种PRNG(伪随机数生成器)。

   /* Print 5 random numbers from 0 to 49 */
   for( i = 0 ; i < n ; i++ ) 
   {

for声明中(用我自己的话说),您会看到<initialization-instruction> ; <condition> ; <loop-instruction>。循环的内容在<condition>为真时执行(以C表示,这意味着非零,但这是一个单独的讨论)。

将之前定义的int i设置为零。虽然i小于n,但请在括号内执行操作,然后递增i++i)并再次检查条件。 (n之前定义为5,因此循环使用值[0, 1, 2, 3, 4]

      printf("%d\n", rand() % 50);

printf()调用使用格式字符串打印其输出。 %d表示您希望printf打印出第一个参数,假设它是无符号十进制整数。如果您在printf调用中包含更多格式字符串,则应在printf()函数中包含多个相应参数。

\n出现在字符或字符串常量中时,是换行符。因此,在打印数字后,光标将移动到下一行的开头。

最后,rand() % 50表示“致电rand(),将结果除以50,然后取余数”。 (%模数运算符,这意味着您需要余数。)例如,如果rand()返回1000,则会将0打印到屏幕,因为1000 % 50 == 0(即1000除以50等于20,余数为0)。

因此最终结果将是打印0到49之间的伪随机值。

   }

   return(0);

这将导致main()完成执行并返回其调用者(可能是任何代码在您的操作系统上加载二进制文件)。它也很可能导致程序的退出状态为0

}