我知道rand()生成一个随机数.我找到了这个例子:
#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);
}
Run Code Online (Sandbox Code Playgroud)
我知道这个问题可能听起来有点傻,但任何人都可以解释一下上面的代码是如何工作的吗?
您应该知道获取有关C标准库的信息的最简单方法是在Linux/UNIX系统上使用手册页.
手册章节3是您可以找到有关标准库的手册页.要获取文档rand,请man 3 rand在shell提示符下键入.
如果你没有方便的手册页,我只想引用这里的描述:
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.
Run Code Online (Sandbox Code Playgroud)
如果你想知道代码本身是如何工作的,我可以为你分解:
#include <stdio.h>
Run Code Online (Sandbox Code Playgroud)
包括标准I/O库.(在这种情况下需要获得定义printf().)
#include <stdlib.h>
Run Code Online (Sandbox Code Playgroud)
包括C标准库(适用于当前平台).这将需要得到的定义rand(),srand()和time().
int main()
Run Code Online (Sandbox Code Playgroud)
定义该函数main(),该函数将在以后作为已编译的可执行文件的入口点进行查找.
{
Run Code Online (Sandbox Code Playgroud)
定义范围main().
int i, n;
Run Code Online (Sandbox Code Playgroud)
在堆栈上为两个int变量分配内存空间i,和n.
time_t t;
Run Code Online (Sandbox Code Playgroud)
在堆栈上为time_t结构分配内存空间,稍后将用于当前时间.
n = 5;
Run Code Online (Sandbox Code Playgroud)
初始化int n为值5.
/* Intializes random number generator */
srand((unsigned) time(&t));
Run Code Online (Sandbox Code Playgroud)
首先调用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++ )
{
Run Code Online (Sandbox Code Playgroud)
在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);
Run Code Online (Sandbox Code Playgroud)
该printf()调用使用格式字符串来打印其输出.在%d你想办法printf打印出假定它是一个无符号十进制整数的第一个参数.如果在printf调用中包含更多格式字符串,则应该在printf()函数中包含多个相应的参数.
的\n,当它出现在一个字符或字符串常量,是一个换行符.因此,在打印数字后,光标将移动到下一行的开头.
最后,rand() % 50意思是"调用rand(),除以结果50,然后取余数".(这%是模数运算符,这意味着你需要余数.)例如,如果rand()返回1000,你将被0打印到屏幕上,因为1000 % 50 == 0(即1000除以50等于20,余数为0).
因此最终结果将是打印0到49之间的伪随机值.
}
return(0);
Run Code Online (Sandbox Code Playgroud)
这将导致main()完成执行并返回其调用者(可能是任何代码在您的操作系统上加载二进制文件).它也很可能导致程序的退出状态0.
}
Run Code Online (Sandbox Code Playgroud)