出自:《C程序设计》(夏宝岚) P76
6.8 编写一个仿骰子程序,将六面体骰子掷6000次,统计出各面出现的次数。每次投掷骰子出现哪一面,由随机数发生器提供的函数经过处理而确定。
#include <stdio.h>
#include <stdlib.h> /* rand()函数用 */
int main()
{
int face;
int f[6] = {0};
int i;
for(i = 1; i <= 6000; i++)
f[rand() % 6]++ ; /* 数组元素下标为0到5 */
printf("Face Frequency\n");
for(face = 0; face < 6; face++)
printf("%2d %10d\n", face + 1, f[face]);
return 0;
}
运行结果(仅供参考):
===============================
Face Frequency
1 1003
2 1017
3 983
4 994
5 1004
6 999
===============================
其中rand()为库函数,函数原型在stdlib.h中定义,其功能是产生0到32767之间的整数,而且每个整数的出现概率是相等的。由于模拟投掷骰子的程序只需要1到6之间的随机整数,故用rand()%6作为数组下标,使数组元素下标为0到5,分别对应1到6各个面。
★ 想既然是随机产生的数,那么每次Run时的结果应该是不一样,但事实上并非如此,我在VC++6.0中得到的上述结果,但每次都是这些值,根本没变。又试着在WIN-TC及TC运行,虽然数据各不相同,但在同一编译器下的结果却总是一样的。
查了一下(查看出处),原来问题在这个rand()函数上。函数原型 int rand(void) 返回一个随机数值,范围在0到RAND_MAX之间,RAND_MAX定义在stdlib.h。看了一下VC++6.0里include目录下的stdlib.h头文件,里面有个"#define RAND_MAX 0x7fff"是十六进制的,也就是十进制的32767。也有称之为伪随机。
在调用这个函数前必须先利用srand()设置好随机数种子。如果未设随机数种子,rand()在调用时会自动设随机数种子为1。是一个不变的值,这样每次运行产生的随机数就是一样的。那如何才能让其为真正的"随机"呢?就要用srand()函数设置rand()函数产生随机数时的随机数种子,其原型为 void srand (unsigned int seed); 其中seed必须为整数,一般可以用geypid()或time(0)的返回值做为seed。如果每次seed都设相同值,rand()所产生的随机数值每次就会一样。改写如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h> /* time()函数用 */
int main()
{
int face;
int f[6] = {0};
int i;
srand(time(0)); /* 设置种子 */
for(i = 1; i <= 6000; i++)
f[rand() % 6]++;
printf("Face Frequency\n");
for(face = 0; face < 6; face++)
printf("%2d %10d\n", face + 1, f[face]);
return 0;
}
运行结果(随机):
==============================
Face Frequency
1 1062
2 940
3 1024
4 974
5 1029
6 971
==============================
再运行(随机):
==============================
Face Frequency
1 978
2 990
3 991
4 1015
5 1047
6 979
==============================
★ 经过如上改动再测试,每次产生的随机数就不一样了。上面是随机选的两组结果。
评论