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

12 篇文章 0 订阅

C语言中,rand()函数可以用来产生随机数,但是这不是真真意义上的随机数,是一个伪随机数,是根据一个数,我们可以称它为种子,为基准以某个递推公式推算出来的一系数,当这系列数很大的时候,就符合正态公布,从而相当于产生了随机数,但这不是真正的随机数,当计算机正常开机后,这个种子的值是定了的,除非你破坏了系统,为了改变这个种子的值,C提供了srand()函数,它的原形是void srand( inta)

可能大家都知道C语言中的随机函数random,可是random函数并不是ANSI C标准,所以说,random函数不能在gcc,vc等编译器下编译通过。

rand()会返回一随机数值,范围在0RAND_MAX间。返回0RAND_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()的种子值返回一个随机数(032767之间)

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产生的随机数从0rand_max,而rand_max是一个很大的数,那么如何产生从X~Y的数呢?

   XY,有YX1个数,所以要产生从XY的数,只需要这样写:

    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-9QQ邮箱的源代码,原理是先用随机函数产生一个<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("===>生成第%dQQ邮箱\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,它的取值范围是从065535
    
  ②           然后,调用rand(   ),是伪随机数,它会根据提供给srand(   )种子值返回一个随机数(在032767之间)。
    
  ③           根据需要多次调用rand(   ),从而不断地得到新的随机数。
    
  ④           无论何时,你都可以给srand(   )提供一个新的种子,从而进一步随机化”rand(   )的输出结果。 
    
  例如,取m=17,则执行了srand(17)之后,再执行rand(   )函数,将得到输出值94;第二次调用rand(   ),会得到26,……反复调用rand(   )就能产生一系列的随机数。 
    
  注意:若m不变,则rand(   )的输出系列也不变,总是94,26,602,……等等。所以,建议摇号的种子选为当前日期或时间,以保证每天的摇号值都不相同。

一个简单的参考程序 彩票选号器 
    
  已调试成功的选号器源程序如下,遗憾的是只有伪随机数字发生器,种子(1-65536)不变则数字不变。因此建议以月日作为种子数(如727日则输入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++) 

//生成1m的随机数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

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值