C语言中的随机数   
作者:王璐
随机数,顾名思义就是随机产生的、无规则的数。在编程中,有时我们不想手动从键盘输入数据,而想让电脑自动产生一些数据供我们使用(例如生成100个两位数),就要用到随机数。
随机数的生成方法很简单,在C语言中,我们通过调用随机函数rand()来产生随机数。rand函数是C语言的标准库函数,和我们常用的输入输出函数(scanfprintf)一样可以在程序中直接调用。
rand函数的用法如下:
首先在程序开头预处理命令部分加上#include<stdlib.h>,其中<stdlib.h>C中的标准库头文件,我们在用rand函数时需要用到这个头文件 [1]。它的作用是为了对rand()函数进行引用性声明,以便在下面的程序中使用它。这和我们在用到scanfprintf函数时需要在程序开头写上#include<stdio.h>(标准输入/输出头文件)是一样的。
随机函数rand使用的格式为:
A=rand()%x+y;
这条语句的意思是,自动产生一个以y为下限,以x+y为上限的随机数,并把值赋给A。即Ayx+y之间的随机数。
例如,有语句:
int a;
a=rand()%89+10;
执行该语句后,a即可得到一个10100之间的整数赋值。
注意区别于:
a=rand()%100;
执行这条语句,a可能取值的上限同样为100,但下限为0a可以取到10以下的数。相当于:a=rand()%100+0;
下面我们来看一个完整的例子:
[eg.1]输入10个两位数,并把他们的和打印出来。
1.从键盘输入数据:
#include<stdio.h>
    void main()
{
        int a[10],sum=0;
int i;
printf("请输入102位数:\printf函数原型在什么头文件里n");
for(i=0;i<10;i++)
{   
scanf("%d",&a[i]);
sum=sum+a[i];
}
printf("\n");
printf("10个数的和是:%d \n",sum);
}
运行结果:
请输入10个两位数:
14  32  47  61  20  17  55  76  29  10
10个数的和是:361
2.使用随机数:
#include<stdio.h>
#include<stdlib.h>
void main()
{
    int a[10],sum=0;
    int i;
    printf("系统自动生成随机数:\n");
    for(i=0;i<10;i++)
    {
        a[i]=rand()%89+10;        /* a10-99之间取值,即a是两位数 */
printf("%d  ",a[i]);
        sum=sum+a[i];
    }
    printf("\n");
    printf("10个两位数的和是:%d \n",sum);   
}
运行结果:
系统自动生成随机数:
51  54  25  77  44  70  96  87  94  88
10个两位数的和是:686
经运行比较后可以感觉到,使用随机数可以简化程序运行,方便人的工作。
要是你够细心,再次运行上面这个程序,观察结果,你会发现两次系统产生的随机数的值是
完全相同的。这里你一定会问,这些数字不是随机产生的吗?两次的结果怎么会一样?
实际上,rand函数产生的是伪随机数。当你调用它,它产生的数看上去是随机的,但每次执行这个程序时,这些数的顺序都会重复。这是因为rand()会用系统指定的某个数做为一个种子,而且这个数是每次开机时就指定好的,如果不通过其他方法为rand()重新指定种子,则在下次开机前该种子数都不会变。所以每次出现的随机数是一样的。这种重复性是函数rand的一个重要特点。
如果你希望在程序完成后,每次运行时产生一组不同的随机数,那么就要用到另一个标准库函数:srand函数。这个函数就可以为rand函数指定任意的种子。在生成随机数的过程中需要我们把randsrand两个函数结合使用,这个过程称为随机化。
使用srand函数,需要由我们给系统提供这个种子,这个种子通常是unsigned(无符号)型。
srand函数使用的格式是:
unsigned seed;    /* 定义种子为无符号型变量 */
srand(seed);    /* 在下边结合使用rand函数,最终生成一组随机数 */
同样,使用这个函数时需要在程序开头写上#include<stdlib.h>
[eg.2]使用srand函数对例1进行改进:
#include<stdio.h>
#include<stdlib.h>
void main()
{
    int a[10],sum=0;
    int i;
    unsigned seed;
    printf("please enter seed:\n");    /* 提示输入一个数,作为种子 */
    scanf("%u",&seed);        /* 注意这里%u用来表示无符号数 */
    srand(seed);            /* 设置随机数生成器的种子 */
    printf("系统自动生成随机数:\n");
    for(i=0;i<10;i++)
    {
        a[i]=rand()%89+10;       
        printf("%d  ",a[i]);
        sum=sum+a[i];
    }
    printf("\n");
    printf("10个两位数的和是:%d \n",sum);
}
让我们将这个程序运行几次,并观察其结果。已经可以获得每次不一样的随机数了。
运行结果:
Please enter seed:
156
系统自动生成随机数:
24  51  84  35  24  94  83  22  15  79
10个两位数的和是:511
再次运行:
Please enter seed:
99
系统自动生成随机数:
15  16  37  54  49  39  58  11  32  39
10个两位数的和是:350
但须注意的是,当输入的种子的值确定时,获得的随机数也会相同。
如:再次输入156作为种子,结果如下:
Please enter seed:
156
系统自动生成随机数:
24  51  84  35  24  94  83  22  15  79
10个两位数的和是:511
如果想让系统自动生成种子,而无需手动输入,可以在例2中程序开头加上:#include<time.h>,并把红部分的语句改为:
srand((unsigned)time(NULL));
其中time()为时间函数,包含在<time.h>头文件中 [2]NULL是参数。这条语句能够在很短的时间内返回计算机的当前时间,并将这个值转换为无符号整数,作为种子。相当于用time(NULL)生成的值替换了例2中的seed.
写出完整的程序后,运行,就能够自动生成不重复的随机数了,并且省去了enter seed的过程。
下面的图可以直观表示srandrand的关系:
[练习题]1.掷骰子游戏:
每个骰子有6个面,分别为1-6点,每掷一次只有一个点数朝上。使用随机数模拟掷6000次骰子的过程,统计掷出每一面的次数。
2.运气游戏:
游戏的规则是:每个玩家每次一起掷两个骰子,计算面朝上的两个点数之和。如果第一次掷的结果是711,那么玩家就获胜。如果第一次掷到2312,玩家就输了,即庄家获胜。如果第一次掷的结果是其他数(4568910)那么玩家需要再次掷骰子,直到掷出的点数与这个结果相同,玩家获胜。但是如果再次掷骰子的过程中掷到了7点,玩家输,庄家获胜。
编程序模拟游戏中玩家掷骰子的过程,要求包含各种不同的投掷情况,并判断玩家获胜/失败。
程序结果举例:
玩家投掷点数:5+6=11
玩家获胜!
玩家投掷点数:4+1=5
点数为5,继续投掷!
玩家投掷点数:3+4=7
玩家失败!
玩家投掷点数:4+1=5
点数为5,继续投掷!
玩家投掷点数:6+2=8
点数为8,继续投掷!
玩家投掷点数:3+2=5
得到相同点数,玩家获胜!
习题1为基础题,习题2为提高题,请根据自身情况选择解答。需要习题参考答案请回复。
关于随机数就说这么多,欢迎大家讨论交流。 
附:
[]1.<stdlib.h>,标准库头文件,包含数字转换到文本以及文本转换到数字的函数原型,还有内存分配、随机数字以及其它实用函数的函数原型。
2.<time.h>,标准库头文件,包含时间和日期操作的函数原型和类型。