在C语言中,rand()函数可以用来产生随机数,但是这不是真真意义上的随机数,是一个伪随机数,是根据一个数,我们可以称它为种子,为基准以某个递推公式推算出来的一系数,当这系列数很大的时候,就符合正态公布,从而相当于产生了随机数,但这不是真正的随机数,当计算机正常开机后,这个种子的值是定了的,除非你破坏了系统,为了改变这个种子的值,C提供了srand()函数,它的原形是void srand( inta)。
可能大家都知道C语言中的随机函数random,可是random函数并不是ANSI C标准,所以说,random函数不能在gcc,vc等编译器下编译通过。
rand()会返回一随机数值,范围在0至RAND_MAX间。返回0至RAND_MAX之间的随机数值,RAND_MAX定义在stdlib.h,(其值至少为32767)我运算的结果是一个不定的数,要看你定义的变量类型,int整形的话就是32767。 在调用此函数产生随机数前,必须先利用srand()设好随机数种子,如果未设随机数种子,rand()在调用时会自动设随机数种子为1。一般用for语句来设置种子的个数。具体见下面的例子。
一 如何产生不可预见的随机序列呢
利用srand((unsigned int)(time(NULL))是一种方法,因为每一次运行程序的时间是不同的。
在C语言里所提供的随机数发生器的用法:现在的C编译器都提供了一个基于ANSI标准的伪随机数发生器函数,用来生成随机数。它们就是rand()和srand()函数。这二个函数的工作过程如下:
1)首先给srand()提供一个种子,它是一个unsigned int类型,其取值范围从0~65535;
2)然后调用rand(),它会根据提供给srand()的种子值返回一个随机数(在0到32767之间)
3)根据需要多次调用rand(),从而不间断地得到新的随机数;
4)无论什么时候,都可以给srand()提供一个新的种子,从而进一步“随机化”rand()的输出结果。
下面是0~32767之间的随机数程序:
#include <stdlib.h>
#include <stdio.h>
#include <time.h> //使用当前时钟做种子
void main( void )
{int i;
srand( (unsigned)time( NULL ) ); //初始化随机数
for( i = 0; i < 10;i++ ) //打印出10个随机数
printf( " %d\n", rand() );
}
根据上面的程序可以很容易得到0~1之间的随机数:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
main( )
{int i;
srand( (unsigned)time( NULL ) );
for( i = 0; i < 10;i++ )
printf( "%5.2f\n", rand()/32767.0);
}
而产生1~100之间的随机数可以这样写:
#include <stdlib.h>
#include <stdio.h>
#include <time.h>
main( )
{int i;
srand( (unsigned)time( NULL ) );
for( i = 0; i < 10;i++ )
printf( "%d\n", rand()%100+1);
}
二,三个通用的随机数发生器,推荐用第三个
函数名: rand
功能:随机数发生器
用法: void rand(void);
程序例:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int i;
printf("Ten random numbers from 0 to 99\n\n");
for(i=0; i<10; i++)
printf("%d\n", rand() % 100);
return 0;
} //这样的一个产生随机数是回出现问题的,因为在开机后运行的产生的随机数是相同的。
三 如何产生设定范围内的随机数
由于rand产生的随机数从0到rand_max,而rand_max是一个很大的数,那么如何产生从X~Y的数呢?
从X到Y,有Y-X+1个数,所以要产生从X到Y的数,只需要这样写:
k=rand()%(Y-X+1)+X;
这样,就可以产生你想要的任何范围内的随机数了。
四,产生不重复的随机数
1) #include <stdlib.h>
#include <stdio.h>
#include<stdio.h>
#include <time.h>
swap(int *pm,int *pn) /*必须用指针进行交换*/
{
int temp;
temp=*pm;
*pm=*pn;
*pn=temp;
}
int main(void)
{
int i,a[513];
/*int *pa,*pb;*/
srand( (unsigned)time( NULL ) ); /*定义这个可以产生不同的随机数*/
for(i=1; i<=512; i++){a[i]=i;printf("%4d",a[i]);}
for(i=512; i>=1; i--)
{
/* pa=&a[i]; pb=&a[rand()%i+1];*/
swap(&a[i], &a[rand()%i+1]); /*加一是从一到i的随机,就不会包含0*/
/*不用再定义指针,这样结论是一样的*/
}
printf("\n") ;
for(i=1; i<=64; i++)
printf("%4d",a[i] );
getch(); /*wintc的输出*/
}
2)
#include <stdlib.h>
#include <stdio.h>
#include<stdio.h>
int main(void)
{
int a[100]={0}; int i,m;
for(i=1; i<=99; ++i)
printf("%4d",a[i] );
srand( (unsigned)time( NULL ) );
for(i=1; i<=99; i++)
{
while(a[m=rand()%100+1]);
a[m] = i;
}
for(i=1; i<=99; ++i)
printf("%4d",a[i] );
getch();
}
随机数,顾名思义就是随机产生的、无规则的数。在编程中,有时我们不想手动从键盘输入数据,而想让电脑自动产生一些数据供我们使用(例如生成100个两位数),就要用到随机数。
随机数的生成方法很简单,在C语言中,我们通过调用随机函数rand()来产生随机数。rand函数是C语言的标准库函数,和我们常用的输入输出函数(scanf和printf)一样可以在程序中直接调用。
rand函数的用法如下:
首先在程序开头预处理命令部分加上#include<stdlib.h>,其中<stdlib.h>是C中的标准库头文件,我们在用rand函数时需要用到这个头文件[见文章最后注1]。它的作用是为了对rand()函数进行引用性声明,以便在下面的程序中使用它。这和我们在用到scanf和printf函数时需要在程序开头写上#include<stdio.h>(标准输入/输出头文件)是一样的。
随机函数rand使用的格式为:
A=rand()%x+y;
这条语句的意思是,自动产生一个以y为下限,以x+y为上限的随机数,并把值赋给A。即A为y到x+y之间的随机数。
例如,有语句:
int a;
a=rand()%89+10;
执行该语句后,a即可得到一个10~100之间的整数赋值。
注意区别于:
a=rand()%100;
执行这条语句,a可能取值的上限同样为100,但下限为0,a可以取到10以下的数。相当于:a=rand()%100+0;
下面我们来看一个完整的例子:
[eg.1]输入10个两位数,并把他们的和打印出来。
1.从键盘输入数据:
#include<stdio.h>
void main()
{
int a[10],sum=0;
int i;
printf("请输入10个2位数:\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;/* a从10-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函数指定任意的种子。在生成随机数的过程中需要我们把rand和srand两个函数结合使用,这个过程称为随机化。
使用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 |
下面是我写的一个用来随机产生7-9位QQ邮箱的源代码,原理是先用随机函数产生一个<10的整数(这个数是所生成QQ号码的位数),然后判断这个数是否在7~9之间,如果满足要求,下面将一位一位地产生每一位数字,最后与"@qq.com"连接,生成一个QQ邮箱,并写入文件.
VC++6.0下编译通过
函数produceQQMail()用来产生随机数的代码:
#include<windows.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define MAX_ADDRESS 1000
char directory[20];
DWORD writeFile(const char*filename,char*str)
{
FILE *fp;
fp=fopen(filename,"a+");
if(fp==NULL)
{
puts("Cannot open this file!");
return -1;
}
fprintf(fp,"%s\n",str);
fflush(fp);
//fputs(str,fp);
return 1;
}
DWORD produceQQMail() //→→→→→产生QQ邮箱函数
{
unsigned int i,count;
char zj[20];
char compare[20];
unsigned long relative;
for(count=1;count<=MAX_ADDRESS;count++)
{
Sleep(600);
srand((unsigned)time(0));
while(1)
{
relative=1+(int)(10.0*rand()/(RAND_MAX+1.0));//产生QQ号码的位数
if(relative<7||relative>9)
continue;//判断是否满足所需要的位数
Sleep(100);
for(i=0;i<relative;i++)
{
itoa(1+(int)(10.0*rand()/(RAND_MAX+1.0)),&zj[i],10);//生成每一位数字,将其转换为字符型,并保存在数组中
}
zj[i]='\0';
strcat(zj,"@qq.com");//连接生成邮箱
if(count>1&&strcmp(compare,zj)==0) //比较前后两者以防出现相同的邮箱
continue;
strcpy(compare,zj);
if(writeFile(directory,zj)==1)
{
printf("===>生成第%d个QQ邮箱\n",count);
//system("cls");
break;
}
}
}
return 1;
}
void main()
{
puts("=>请输入您要保存到的文件名及其目录");
scanf("%s",directory);
puts("=>Now producing QQ mail addresses……");
produceQQMail();
}
随机数是怎么产生出来的呢?
可以利用C语言中的种子函数srand( )和伪随机函数rand( )来实现。
① 首先,给srand(m )提供一个“种子”m,它的取值范围是从0~65535。
② 然后,调用rand( ),是伪随机数,它会根据提供给srand( )的“种子”值返回一个随机数(在0~32767之间)。
③ 根据需要多次调用rand( ),从而不断地得到新的随机数。
④ 无论何时,你都可以给srand( )提供一个新的“种子”,从而进一步“随机化”rand( )的输出结果。
例如,取m=17,则执行了srand(17)之后,再执行rand( )函数,将得到输出值94;第二次调用rand( ),会得到26,……反复调用rand( )就能产生一系列的随机数。
注意:若m不变,则rand( )的输出系列也不变,总是94,26,602,……等等。所以,建议摇号的“种子”选为当前日期或时间,以保证每天的摇号值都不相同。
一个简单的参考程序 彩票选号器
已调试成功的选号器源程序如下,遗憾的是只有伪随机数字发生器,种子(1-65536)不变则数字不变。因此建议以月日作为种子数(如7月27日则输入727)
#include<stdio.h> /*全局变量及函数提前说明:*/
#include<stdlib.h>
typedef struct liuyu{int data;struct liuyu*link;}test;
liuyu *p,*q,*r,*head;
int L; /*元素的个数*/
int m=sizeof(test);
void build(); /*生成数字循环链表*/
void display(); /*输出链表*/
/*---------------------------------------------------------*/
void build() /*数字循环链表的生成*/
{int i;
head=(test*)malloc(m); /*m=sizeof(test);*/
p=head;
for(i=1;i<L;i++)
{p->data=i;
p->link=(test*)malloc(m); /*m=sizeof(test));*/
p=p->link;
}
p->data=i;
p->link=head;
}
/*---------------------------------------------------------*/
void display() /*数字循环链表的输出*/
{p=head;
while (p->link!=head)
{printf("%3d",p->data);
p=p->link;
}
printf("%3d\n",p->data);
}
/*---------------------------------------------------------*/
void main(void) /* 输出福彩1-36个数字中的7个随机号码*/
{ L=36;
int n,i,j;
build();
printf("random number=");
scanf("%d",&n);
srand(n);
p=head;
for(j=1;j<=7;j++)
{n=rand();
for(i=1;i<=n;i++)
{q=p; /* 删除元素X,注意保存X的前趋元素指针! */
p=p->link;}
printf("%d",p->data);
q->link=p->link;
}
/*---------------------------------------------------------*/
L=10; /* 马上接着运行体彩10中选7程序 */
build();
printf("\nrandom number2=");
scanf("%d",&n);
srand(n);
printf("\n\n");
p=head;
for(j=1;j<=7;j++)
{n=rand();
for(i=1;i<=n;i++)p=p->link;
if(p->data==10)p->data=0;
printf("%d",p->data);
}
}
4位数字是没有重复的吧
#include<iostream.h>
#include<stdlib.h>
#include<time.h>
void rnd4(int b[])
{
int a[10];
for(int i=0;i<10;i++)
{
a[i]=i;
}
int m=10;
for(i=0;i<4;i++)
{
//生成1到m的随机数rn
int rn=rand()%m;
b[i]=a[rn];
m--;
//把a[rn]放到数组a的末端
int temp=a[m];
a[m]=a[rn];
a[rn]=temp;
}
}
void main()
{
srand(time(0));
int b[4];
rnd4(b);
}
//b即是你要的数组
看看得不得:
#include "stdio.h"
#include "math.h"
#define N 3 /*根据你的需要而定*/
void main()
{
int a[N];
int j;
for(j=0;j<N;j++)
for(;;)
{
a[j]=rand();
if(a[j]>=1000&&a[j]<10000) break;
}
for(j=0;j<N;j++)
printf("a[%d]=%d\n",j,a[j]);
}
转自:http://user.qzone.qq.com/1174632606/infocenter#!app=2&via=QZ.HashRefresh&pos=1321774224