C和C随机数或字符串生成源码_第1页
C和C随机数或字符串生成源码_第2页
免费预览已结束,剩余6页可下载查看

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、本文档如对你有帮助,请帮忙下载支持!1.基本函数在 C 语言中取随机数所需要的函数是:int rand(void);void srand(unsignedint n);rand()函数和 srand()函数被声明在头文件 stdlib.h 中,所以要使用这两个函数必须包含该头文件:#inelude 2.使用方法rand()函数返回 0 至 U RAND_MAX 之间的伪随机数(pseudorandom) 。RAND_MAX 常量被定义在 stdlib.h 头文件中。其值等于 32767,或者更大。srand()函数使用自变量 n 作为种子,用来初始化随机数产生器。只要把相同的种子传入 sran

2、d(),然后调用 rand()时,就会产生相同的随机数序列。因此,我们可以把时间作为srand()函数的种子,就可以避免重复的发生。如果,调用 rand()之前没有先调用 srand(),就和事先调用 srand(1)所产生的结果一 样。/*例 1 :不指定种子的值*/for (int i=0; i10; i+)printf(%d , rand()%10);每次运行都将输出:1 7 4 0 9 4 8 8 2 4/*例 2:指定种子的值为 1 */sran c(1);for (int i=0; i10; i+)printf(%d , rand()%10);每次运行都将输出:1 7 4 0 9

3、4 8 8 2 4 例 2 的输岀结果与例 1 是完全一样的。/*例 3:指定种子的值为 8 */sran c(8);for (int i=0; i10; i+)printf(%d , rand()%10);每次运行都将输出:4 0 1 3 5 3 7 7 1 5该程序取得的随机值也是在0,10 )之间,与 srand(1)所取得的值不同,但是每次运行程序的结果都相 同。/*例 4:指定种子值为现在的时间*/sranc(unsignec)time(NULL);本文档如对你有帮助,请帮忙下载支持!for (int i=0; i10; i+)printf(%d , rand()%10);该程序每次

4、运行结果都不一样,因为每次启动程序的时间都不同。另外需要注意的是,使用time()函数前必须包含头文件 time.h 。3.注意事项求一定范围内的随机数。如要取0,10)之间的随机整数,需将 rand()的返回值与 10 求模。randnumber= rand() % 10;那么,如果取的值不是从 0 开始呢?你只需要记住一个通用的公式。要取a,b)之间的随机整数(包括 a,但不包括 b),使用:(rand() % (b - a) + a伪随机浮点数。要取得 01 之间的浮点数,可以用:rand() / (double)(RAND_MAX)如果想取更大范围的随机浮点数,比如0100,可以采用如

5、下方法:rand() /(double)(RAND_MAX)/100)其他情况,以此类推,这里不作详细说明。当然,本文取伪随机浮点数的方法只是用来说明函数的使用办法,你可以采用更好的方法来实现。举个例子,假设我们要取得010 之间的随机整数(不含 10 本身):大家可能很多次讨论过随机数在计算机中怎样产生的问题,在这篇文章中,我会对这个问题进行更深入的 探讨,阐述我对这个问题的理解。首先需要声明的是,计算机不会产生绝对随机的随机数,计算机只能产生伪随机数”。其实绝对随机的随机数只是一种理想的随机数,即使计算机怎样发展,它也不会产生一串绝对随机的随机数。计算机只 能生成相对的随机数,即伪随机数。

6、伪随机数并不是假随机数,这里的伪”是有规律的意思,就是计算机产生的伪随机数既是随机的又是有规律的。怎样理解呢?产生的伪随机数有时遵守一定的规律,有时不遵守任何规律;伪随机数有一部分遵守一定的规律;另一部分不遵守任何规律。比如世上没有两片形状完全相同的树叶 ”,这正是点到了事物的特性,即随机性,但是每种树的叶子都有近似的形状,这正是事物的共性,即规律性。从这个角度讲, 你大概就会接受这样的事实了:计算机只能产生伪随机数而不能产生绝对随机的随机数。那么计算机中随机数是怎样产生的呢?有人可能会说,随机数是由随机种子”产生的。没错,随机种子是用来产生随机数的一个数,在计算机中,这样的一个 随机种子”是

7、一个无符号整形数。那么随机种子 是从哪里获得的呢?下面看这样一个 C 程序:/ran dOl.c本文档如对你有帮助,请帮忙下载支持!#in cludestatic un sig nedi nt RAND_SEED;un sig nedi nt ran dom(void)RAND_SEED =(RAND_SEED * 123+59)%65536;return( RAND_SEED);void ran dom_stari(void)int temp2;movedata(0 x0040,0 x006c,FP_SEGtemp),FP_OFF(temp),4);RAND_SEED=temp0;mai n

8、()un sig nedi nt i,n; ran dom_star(); for(i=0;i10;i+) prin tf (%ut ,ran dom();prin tf(n);这个程序(randOl.c )完整地阐述了随机数产生的过程:首先,主程序调用 random_start() 方法,random_start()方法中的这一句我很感兴趣:movedata(0 x0040,0 x006c,FP_SEG(temp),FP_OFF(temp),4);这个函数用来移动内存数据,其中FP_SEG (far pointer to segment)是取 temp 数组段地址的函数,FP_OFF ( f

9、ar pointer to offset )是取 temp 数组相对地址的函数,movedata 函数的作用是把位于 0040:006CH存储单元中的双字放到数组 temp 的声明的两个存储单元中。这样可以通过 temp 数组把 0040:006CH 处的一个 16 位的数送给 RAND_SEED。random 用来根据随机种子 RAND_SEED 的值计算得出随机数,其中这一句:RAND_SEED = (RAND_SEED*123+59)%65536;是用来计算随机数的方法,随机数的计算方法在不同的计算机中是不同的,即使在相同的计算机中安 装的不同的操作系统中也是不同的。我在linux 和

10、windows 下分别试过,相同的随机种子在这两种操作本文档如对你有帮助,请帮忙下载支持!系统中生成的随机数是不同的,这说明它们的计算方法不同。现在,我们明白随机种子是从哪儿获得的,而且知道随机数是怎样通过随机种子计算岀来的了。那么,随机种子为什么要在内存的 0040:006CH 处取? 0040:006CH处存放的是什么?学过计算机组成原理与接口技术这门课的人可能会记得在编制ROM BIOS 时钟中断服务程序时会用到 Intel 8253 定时/计数器,它与 Intel 8259中断芯片的通信使得中断服务程序得以运转,主板每秒产生的 18.2 次中断正是处理器根据定时/记数器值控制中断芯片产

11、生的。在我们计算机的主机板上都会 有这样一个定时/记数器用来计算当前系统时间,每过一个时钟信号周期都会使记数器加一,而这个记数器的值存放在哪儿呢?没错,就在内存的0040:006CH处,其实这一段内存空间是这样定义的:TIMER_LOW DW ?;地址为 0040:006CHTIMER_HIGH DW ?;地址为 0040:006EHTIMER_OFT DB ?;地址为 0040:0070H时钟中断服务程序中,每当TIMER_LOW 转满时,此时,记数器也会转满,记数器的值归零,即TIMER_LOW 处的 16 位二进制归零,而 TIMER_HIGH 加一。rand01.c 中的movedat

12、a(0 x0040,0 x006c,FP_SEG(temp),FP_0FF(temp),4);正是把 TIMER_LOW 和 TIMER_HIGH 两个 16 位二进制数放进 temp 数组,再送往 RAND_SEED , 从而获得了随机种子”。现在,可以确定的一点是,随机种子来自系统时钟,确切地说,是来自计算机主板上的定时/计数器在内存中的记数值。这样,我们总结一下前面的分析,并讨论一下这些结论在程序中的应用:1.随机数是由随机种子根据一定的计算方法计算岀来的数值。所以,只要计算方法一定,随机种子一 定,那么产生的随机数就不会变。看下面这个 C+程序:/ran d02.cpp#include

13、 #include using n amespacestd;int main()un sig nedi nt seed= 5;sran dfseed;un sig nedi nt r = ran d();cout r endl;在相同的平台环境下,编译生成 exe 后,每次运行它,显示的随机数都是一样的。这是因为在相同的 编译平台环境下,由随机种子生成随机数的计算方法都是一样的,再加上随机种子一样,所以产生的随机 数就是一样的。2.只要用户或第三方不设置随机种子,那么在默认情况下随机种子来自系统时钟(即定时/计数器的值)本文档如对你有帮助,请帮忙下载支持!看下面这个 C+程序:/ran d03

14、.cpp#include #include using n amespacestd;int main()sranc(unsigned)time(NULL);un sig nedi nt r = ran d();cout r endl;return 0;这里用户和其他程序没有设定随机种子,则使用系统定时/计数器的值做为随机种子,所以,在相同的平台环境下,编译生成 exe 后,每次运行它,显示的随机数会是伪随机数,即每次运行显示的结果会有不 同。3.建议:如果想在一个程序中生成随机数序列,需要至多在生成随机数之前设置一次随机种子。看下面这个用来生成一个随机字符串的C+程序:/ran d04.cpp

15、#in clude#in cludeusing namespacestd;int mai n()in t rNum,m = 20;char*ch = new charm;for (int i = 0; i m; i+ )本文档如对你有帮助,请帮忙下载支持!大家看到了,随机种子会随着 for 循环在程序中设置多次sranc(unsigned)time(NULL )*j);/j 是后加的外层循环rNum = 1+(int)(rand()/(double)RAND_MAX )*36); 求随机值switch (rNum)easel: chi=a;break;case2: chi=b;break;ca

16、se3: chi=c;break;case4: chi=d;break;case5: chi=e;break;case6: chi=f;break;case7: chi=g:break;case8: chi=h; break;case9: chi=i; break;case10: chi=j; break;casell: chi=k;break;case12: chi=T; break;case13: chi=m; break;case14: chi= n:break;case15: chi=o; break;case16: chi=p;本文档如对你有帮助,请帮忙下载支持!break;case

17、17: chi=q; break;case18: chi=r; break;case19: chi=s; break;case20: chi=t; break;case21: chi=u:break;case22: chi=v;break;case23: chi=w;break;case24: chi=x;break;case25: chi=y;break;case26: chi=z;break;case27:chi=O;break;case28:chi=1;break;case29:chi=2;break;case30:chi=3;break;case31:chi=4;break;case3

18、2:chi=5;break;case33:chi=6;本文档如对你有帮助,请帮忙下载支持!break;case34:chi=7;break;case35:chi=8;break;case36:chi=9;break;/e nd of switchcout chi; /end of for loopcout endl;delete ch;return 0;而运行结果显示的随机字符串的每一个字符都是一样的,也就是说生成的字符序列不随机,所以我们需要把 srand(unsigned)time(NULL);从 for 循环中移出放在 for 语句前面,这样可以生成随机的字符序列,而且每次运行生成的字符序列会不同(呵呵,也有可能相同,不过出现这种情况的几率太小了)。如果你把 srand(unsigned)time(NULL)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论