C和C隨機(jī)數(shù)或字符串生成源碼_第1頁(yè)
C和C隨機(jī)數(shù)或字符串生成源碼_第2頁(yè)
已閱讀5頁(yè),還剩3頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、本文檔如對(duì)你有幫助,請(qǐng)幫忙下載支持!1.基本函數(shù)在 C 語(yǔ)言中取隨機(jī)數(shù)所需要的函數(shù)是:int rand(void);void srand(unsignedint n);rand()函數(shù)和 srand()函數(shù)被聲明在頭文件 stdlib.h 中,所以要使用這兩個(gè)函數(shù)必須包含該頭文件:#inelude 2.使用方法rand()函數(shù)返回 0 至 U RAND_MAX 之間的偽隨機(jī)數(shù)(pseudorandom) 。RAND_MAX 常量被定義在 stdlib.h 頭文件中。其值等于 32767,或者更大。srand()函數(shù)使用自變量 n 作為種子,用來(lái)初始化隨機(jī)數(shù)產(chǎn)生器。只要把相同的種子傳入 sran

2、d(),然后調(diào)用 rand()時(shí),就會(huì)產(chǎn)生相同的隨機(jī)數(shù)序列。因此,我們可以把時(shí)間作為srand()函數(shù)的種子,就可以避免重復(fù)的發(fā)生。如果,調(diào)用 rand()之前沒(méi)有先調(diào)用 srand(),就和事先調(diào)用 srand(1)所產(chǎn)生的結(jié)果一 樣。/*例 1 :不指定種子的值*/for (int i=0; i10; i+)printf(%d , rand()%10);每次運(yùn)行都將輸出: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);每次運(yùn)行都將輸出:1 7 4 0 9

3、4 8 8 2 4 例 2 的輸岀結(jié)果與例 1 是完全一樣的。/*例 3:指定種子的值為 8 */sran c(8);for (int i=0; i10; i+)printf(%d , rand()%10);每次運(yùn)行都將輸出:4 0 1 3 5 3 7 7 1 5該程序取得的隨機(jī)值也是在0,10 )之間,與 srand(1)所取得的值不同,但是每次運(yùn)行程序的結(jié)果都相 同。/*例 4:指定種子值為現(xiàn)在的時(shí)間*/sranc(unsignec)time(NULL);本文檔如對(duì)你有幫助,請(qǐng)幫忙下載支持!for (int i=0; i10; i+)printf(%d , rand()%10);該程序每次

4、運(yùn)行結(jié)果都不一樣,因?yàn)槊看螁?dòng)程序的時(shí)間都不同。另外需要注意的是,使用time()函數(shù)前必須包含頭文件 time.h 。3.注意事項(xiàng)求一定范圍內(nèi)的隨機(jī)數(shù)。如要取0,10)之間的隨機(jī)整數(shù),需將 rand()的返回值與 10 求模。randnumber= rand() % 10;那么,如果取的值不是從 0 開(kāi)始呢?你只需要記住一個(gè)通用的公式。要取a,b)之間的隨機(jī)整數(shù)(包括 a,但不包括 b),使用:(rand() % (b - a) + a偽隨機(jī)浮點(diǎn)數(shù)。要取得 01 之間的浮點(diǎn)數(shù),可以用:rand() / (double)(RAND_MAX)如果想取更大范圍的隨機(jī)浮點(diǎn)數(shù),比如0100,可以采用如

5、下方法:rand() /(double)(RAND_MAX)/100)其他情況,以此類推,這里不作詳細(xì)說(shuō)明。當(dāng)然,本文取偽隨機(jī)浮點(diǎn)數(shù)的方法只是用來(lái)說(shuō)明函數(shù)的使用辦法,你可以采用更好的方法來(lái)實(shí)現(xiàn)。舉個(gè)例子,假設(shè)我們要取得010 之間的隨機(jī)整數(shù)(不含 10 本身):大家可能很多次討論過(guò)隨機(jī)數(shù)在計(jì)算機(jī)中怎樣產(chǎn)生的問(wèn)題,在這篇文章中,我會(huì)對(duì)這個(gè)問(wèn)題進(jìn)行更深入的 探討,闡述我對(duì)這個(gè)問(wèn)題的理解。首先需要聲明的是,計(jì)算機(jī)不會(huì)產(chǎn)生絕對(duì)隨機(jī)的隨機(jī)數(shù),計(jì)算機(jī)只能產(chǎn)生偽隨機(jī)數(shù)”。其實(shí)絕對(duì)隨機(jī)的隨機(jī)數(shù)只是一種理想的隨機(jī)數(shù),即使計(jì)算機(jī)怎樣發(fā)展,它也不會(huì)產(chǎn)生一串絕對(duì)隨機(jī)的隨機(jī)數(shù)。計(jì)算機(jī)只 能生成相對(duì)的隨機(jī)數(shù),即偽隨機(jī)數(shù)。

6、偽隨機(jī)數(shù)并不是假隨機(jī)數(shù),這里的偽”是有規(guī)律的意思,就是計(jì)算機(jī)產(chǎn)生的偽隨機(jī)數(shù)既是隨機(jī)的又是有規(guī)律的。怎樣理解呢?產(chǎn)生的偽隨機(jī)數(shù)有時(shí)遵守一定的規(guī)律,有時(shí)不遵守任何規(guī)律;偽隨機(jī)數(shù)有一部分遵守一定的規(guī)律;另一部分不遵守任何規(guī)律。比如世上沒(méi)有兩片形狀完全相同的樹(shù)葉 ”,這正是點(diǎn)到了事物的特性,即隨機(jī)性,但是每種樹(shù)的葉子都有近似的形狀,這正是事物的共性,即規(guī)律性。從這個(gè)角度講, 你大概就會(huì)接受這樣的事實(shí)了:計(jì)算機(jī)只能產(chǎn)生偽隨機(jī)數(shù)而不能產(chǎn)生絕對(duì)隨機(jī)的隨機(jī)數(shù)。那么計(jì)算機(jī)中隨機(jī)數(shù)是怎樣產(chǎn)生的呢?有人可能會(huì)說(shuō),隨機(jī)數(shù)是由隨機(jī)種子”產(chǎn)生的。沒(méi)錯(cuò),隨機(jī)種子是用來(lái)產(chǎn)生隨機(jī)數(shù)的一個(gè)數(shù),在計(jì)算機(jī)中,這樣的一個(gè) 隨機(jī)種子”是

7、一個(gè)無(wú)符號(hào)整形數(shù)。那么隨機(jī)種子 是從哪里獲得的呢?下面看這樣一個(gè) C 程序:/ran dOl.c本文檔如對(duì)你有幫助,請(qǐng)幫忙下載支持!#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);這個(gè)程序(randOl.c )完整地闡述了隨機(jī)數(shù)產(chǎn)生的過(guò)程:首先,主程序調(diào)用 random_start() 方法,random_start()方法中的這一句我很感興趣:movedata(0 x0040,0 x006c,FP_SEG(temp),FP_OFF(temp),4);這個(gè)函數(shù)用來(lái)移動(dòng)內(nèi)存數(shù)據(jù),其中FP_SEG (far pointer to segment)是取 temp 數(shù)組段地址的函數(shù),F(xiàn)P_OFF ( f

9、ar pointer to offset )是取 temp 數(shù)組相對(duì)地址的函數(shù),movedata 函數(shù)的作用是把位于 0040:006CH存儲(chǔ)單元中的雙字放到數(shù)組 temp 的聲明的兩個(gè)存儲(chǔ)單元中。這樣可以通過(guò) temp 數(shù)組把 0040:006CH 處的一個(gè) 16 位的數(shù)送給 RAND_SEED。random 用來(lái)根據(jù)隨機(jī)種子 RAND_SEED 的值計(jì)算得出隨機(jī)數(shù),其中這一句:RAND_SEED = (RAND_SEED*123+59)%65536;是用來(lái)計(jì)算隨機(jī)數(shù)的方法,隨機(jī)數(shù)的計(jì)算方法在不同的計(jì)算機(jī)中是不同的,即使在相同的計(jì)算機(jī)中安 裝的不同的操作系統(tǒng)中也是不同的。我在linux 和

10、windows 下分別試過(guò),相同的隨機(jī)種子在這兩種操作本文檔如對(duì)你有幫助,請(qǐng)幫忙下載支持!系統(tǒng)中生成的隨機(jī)數(shù)是不同的,這說(shuō)明它們的計(jì)算方法不同。現(xiàn)在,我們明白隨機(jī)種子是從哪兒獲得的,而且知道隨機(jī)數(shù)是怎樣通過(guò)隨機(jī)種子計(jì)算岀來(lái)的了。那么,隨機(jī)種子為什么要在內(nèi)存的 0040:006CH 處??? 0040:006CH處存放的是什么?學(xué)過(guò)計(jì)算機(jī)組成原理與接口技術(shù)這門課的人可能會(huì)記得在編制ROM BIOS 時(shí)鐘中斷服務(wù)程序時(shí)會(huì)用到 Intel 8253 定時(shí)/計(jì)數(shù)器,它與 Intel 8259中斷芯片的通信使得中斷服務(wù)程序得以運(yùn)轉(zhuǎn),主板每秒產(chǎn)生的 18.2 次中斷正是處理器根據(jù)定時(shí)/記數(shù)器值控制中斷芯片產(chǎn)

11、生的。在我們計(jì)算機(jī)的主機(jī)板上都會(huì) 有這樣一個(gè)定時(shí)/記數(shù)器用來(lái)計(jì)算當(dāng)前系統(tǒng)時(shí)間,每過(guò)一個(gè)時(shí)鐘信號(hào)周期都會(huì)使記數(shù)器加一,而這個(gè)記數(shù)器的值存放在哪兒呢?沒(méi)錯(cuò),就在內(nèi)存的0040:006CH處,其實(shí)這一段內(nèi)存空間是這樣定義的:TIMER_LOW DW ?;地址為 0040:006CHTIMER_HIGH DW ?;地址為 0040:006EHTIMER_OFT DB ?;地址為 0040:0070H時(shí)鐘中斷服務(wù)程序中,每當(dāng)TIMER_LOW 轉(zhuǎn)滿時(shí),此時(shí),記數(shù)器也會(huì)轉(zhuǎn)滿,記數(shù)器的值歸零,即TIMER_LOW 處的 16 位二進(jìn)制歸零,而 TIMER_HIGH 加一。rand01.c 中的movedat

12、a(0 x0040,0 x006c,FP_SEG(temp),FP_0FF(temp),4);正是把 TIMER_LOW 和 TIMER_HIGH 兩個(gè) 16 位二進(jìn)制數(shù)放進(jìn) temp 數(shù)組,再送往 RAND_SEED , 從而獲得了隨機(jī)種子”。現(xiàn)在,可以確定的一點(diǎn)是,隨機(jī)種子來(lái)自系統(tǒng)時(shí)鐘,確切地說(shuō),是來(lái)自計(jì)算機(jī)主板上的定時(shí)/計(jì)數(shù)器在內(nèi)存中的記數(shù)值。這樣,我們總結(jié)一下前面的分析,并討論一下這些結(jié)論在程序中的應(yīng)用:1.隨機(jī)數(shù)是由隨機(jī)種子根據(jù)一定的計(jì)算方法計(jì)算岀來(lái)的數(shù)值。所以,只要計(jì)算方法一定,隨機(jī)種子一 定,那么產(chǎn)生的隨機(jī)數(shù)就不會(huì)變??聪旅孢@個(gè) 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;在相同的平臺(tái)環(huán)境下,編譯生成 exe 后,每次運(yùn)行它,顯示的隨機(jī)數(shù)都是一樣的。這是因?yàn)樵谙嗤?編譯平臺(tái)環(huán)境下,由隨機(jī)種子生成隨機(jī)數(shù)的計(jì)算方法都是一樣的,再加上隨機(jī)種子一樣,所以產(chǎn)生的隨機(jī) 數(shù)就是一樣的。2.只要用戶或第三方不設(shè)置隨機(jī)種子,那么在默認(rèn)情況下隨機(jī)種子來(lái)自系統(tǒng)時(shí)鐘(即定時(shí)/計(jì)數(shù)器的值)本文檔如對(duì)你有幫助,請(qǐng)幫忙下載支持!看下面這個(gè) 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;這里用戶和其他程序沒(méi)有設(shè)定隨機(jī)種子,則使用系統(tǒng)定時(shí)/計(jì)數(shù)器的值做為隨機(jī)種子,所以,在相同的平臺(tái)環(huán)境下,編譯生成 exe 后,每次運(yùn)行它,顯示的隨機(jī)數(shù)會(huì)是偽隨機(jī)數(shù),即每次運(yùn)行顯示的結(jié)果會(huì)有不 同。3.建議:如果想在一個(gè)程序中生成隨機(jī)數(shù)序列,需要至多在生成隨機(jī)數(shù)之前設(shè)置一次隨機(jī)種子??聪旅孢@個(gè)用來(lái)生成一個(gè)隨機(jī)字符串的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+ )本文檔如對(duì)你有幫助,請(qǐng)幫忙下載支持!大家看到了,隨機(jī)種子會(huì)隨著 for 循環(huán)在程序中設(shè)置多次sranc(unsigned)time(NULL )*j);/j 是后加的外層循環(huán)rNum = 1+(int)(rand()/(double)RAND_MAX )*36); 求隨機(jī)值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;本文檔如對(duì)你有幫助,請(qǐng)幫忙下載支持!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;本文檔如對(duì)你有幫助,請(qǐng)幫忙下載支持!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;而運(yùn)行結(jié)果顯示的隨機(jī)字符串的每一個(gè)字符都是一樣的,也就是說(shuō)生成的字符序列不隨機(jī),所以我們需要把 srand(unsigned)time(NULL);從 for 循環(huán)中移出放在 for 語(yǔ)句前面,這樣可以生成隨機(jī)的字符序列,而且每次運(yùn)行生成的字符序列會(huì)不同(呵呵,也有可能相同,不過(guò)出現(xiàn)這種情況的幾率太小了)。如果你把 srand(unsigned)time(NULL)

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論