c语言中的rand()函数和srand()函数产生随机的整数

     在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]);
}
  • 8
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值