詳解C語言隨機數(shù)設(shè)置的三種方式(保姆級教程)
前言
本篇文章將為大家介紹在C語言中如何設(shè)置隨機數(shù),在設(shè)置隨機數(shù)的過程中,大家可能會遇到以下問題:
1、每次進入程序后的隨機數(shù)與上一次相同。
2、當隨機數(shù)設(shè)置過快時,可能會相同。
3、如何設(shè)置指定范圍的隨機數(shù)。
隨機數(shù)設(shè)置三板斧
在設(shè)置隨機數(shù)的時候,我們需要用到三個函數(shù),它們分別是rand,time,srand。下面將一一進行講解:
第一式:rand函數(shù)
我們可以打開MSDN去看看rand函數(shù)的定義:

rand函數(shù)的參數(shù)為空,返回值是一個0到RAND_MAX的整型數(shù)字。轉(zhuǎn)到定義,我們可以看到,RAND_MAX的值為0x7fff。轉(zhuǎn)為十進制為32767。

下面我們可以寫一段代碼生成10個隨機數(shù)并將它打印出來:
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
int ret = rand();
printf("%d ", ret);
}
printf("\n");
return 0;
}我們可以運行看看,可以得到10個隨機數(shù)字:

但是細心的小伙伴就發(fā)現(xiàn)了(記得自己敲代碼觀察結(jié)果,由于本人不會做動圖,就麻煩各位佬自己敲代碼看了),好像每次運行代碼生成的10個隨機數(shù)都是一樣的。那是因為我們沒有設(shè)置隨機數(shù)種子,下面我們將講解如何設(shè)置隨機數(shù)種子:
第二式:srand函數(shù)
再次打開MSDN,查看我們的srand函數(shù)的定義:

我們可以看到:srand函數(shù)的參數(shù)為一個無符號整型數(shù)字,返回值為零,隨機數(shù)種子的設(shè)置是為了生成隨機數(shù)。
下面我們將設(shè)置一個隨即數(shù)種子再次生成10個隨機數(shù):
int main()
{
int i = 0;
srand(666);
for (i = 0; i < 10; i++)
{
int ret = rand();
printf("%d ", ret);
}
printf("\n");
return 0;
}好了,這次我們設(shè)置了一個隨機數(shù)種子,這下應(yīng)該不會出問題了吧。我們再次運行我們的代碼:

細心的朋友又又又會發(fā)現(xiàn)了,這次怎么還是不管運行多少次代碼,結(jié)果還是一樣的呀,作者你這不坑人嘛!各位佬請冷靜,當srand函數(shù)中的參數(shù)是一個變化的數(shù)的時候我們才會生成真正的隨機數(shù)(就像你遇到一個路口,每次你都進入同一個路口,那盡頭不都是一樣的嘛,只有當你選擇不同的路口進入的時候終點才不一樣)。那這個時候又有小伙伴要說話了,作者你拿我尋開心呢?你說要生成一個隨機數(shù),這里你用srand又要用一個變化的參數(shù),這不兩頭難嘛?
xdm別急。不妨想想在我們的計算機中什么是變化的?那不就是時間嘛?時間可是無時無刻不在改變。
小結(jié):當我們在調(diào)用rand函數(shù)生成隨機數(shù)的時候。我們需要設(shè)置隨機數(shù)種子,如果我們設(shè)置的隨機數(shù)種子相同,那么產(chǎn)生的隨機數(shù)也是相同的,所以這時候我們就要設(shè)置不同的隨機數(shù)種子。在計算機中時間是變化的,所以我們可以用時間來做隨機數(shù)種子,每次程序運行的時間都不同,這樣就可以得到我們的隨機數(shù)了。
這里就要講到我們的time函數(shù)了
第三式:time函數(shù)
這里我們先講講時間戳:
Unix時間戳是指從1970年1月1日開始所經(jīng)過的秒數(shù),不考慮閏秒。
再次查看time函數(shù)的定義:(ps:C語言中的time函數(shù)調(diào)用后會返回一個時間戳)

這里的time_t的本質(zhì)其實是一個64位的整型。我們可以看到time函數(shù)的參數(shù)是一個指針,那我們直接給他傳一個空指針就可以了。
值得注意的是:這里的返回值類型為time_t,有的編譯器可能會發(fā)生警告,為了防止編譯器警告,我們可以將它強制轉(zhuǎn)換為unsigned int類型。
那么現(xiàn)在我們就可以解決剛剛的問題了,我們修改一下代碼,再次運行。
int main()
{
int i = 0;
srand((unsigned int)time(NULL));
for (i = 0; i < 10; i++)
{
int ret = rand();
printf("%d ", ret);
}
time_t;
printf("\n");
return 0;
}現(xiàn)在我們運行程序的話就會發(fā)現(xiàn),隨機數(shù)生成成功了。
常見問題:
1、每次進入程序后的隨機數(shù)與上一次相同。
這是因為我們在設(shè)置隨機數(shù)的時候 沒有設(shè)置種子 或者 設(shè)置種子的srand函數(shù)中的參數(shù)不是一個變化的值(參數(shù)不是時間戳)。
2、當隨機數(shù)設(shè)置過快時,可能會相同。
在設(shè)置隨機數(shù)的時候,我們只需要設(shè)置一個隨機種子就行了,如果我們每生成一個隨機數(shù)就設(shè)置一個隨機種子的話,由于程序運行的時間太快,可能時間戳會相同,從而產(chǎn)生的隨機數(shù)也一樣。
例如:
int main()
{
int i = 0;
for (i = 0; i < 10; i++)
{
srand(time(NULL));
int ret = rand();
printf("%d ", ret);
}
time_t;
printf("\n");
return 0;
}我們運行一下程序:

所以,我們在設(shè)置隨機數(shù)的時候一定要檢查是否只設(shè)置了一個隨機數(shù)。
3、如何設(shè)置指定范圍的隨機數(shù)。
在設(shè)置隨機數(shù)的時候,如果我們想要生成的隨機數(shù)在一定范圍內(nèi),那么我們就要對隨機數(shù)進行一點小小的處理:
如果想要生成的隨機數(shù)落在(0,n)
int q = rand()%(n+1) //生成的數(shù)與(n+1)整除,所以不包含n+1
隨機數(shù)落在(1,n)
int q = rand()%n + 1;
隨機數(shù)可以根據(jù)我們的需要進行設(shè)置,希望各位小伙伴能夠靈活運用,今天的分享就到這里了,希望我的文章能夠幫助到大家。要是有什么不對的地方也請各位指正。目前文章可能排版不是很好,但是我會努力的,希望自己的文章能夠越寫越好。祝各位水平越來越高,都能拿到好offer。
到此這篇關(guān)于詳解C語言隨機數(shù)設(shè)置的三種方式(保姆級教程)的文章就介紹到這了,更多相關(guān)C語言隨機數(shù)設(shè)置內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C 創(chuàng)建鏈表并將信息存儲在二進制文件中讀取的實例代碼
C 創(chuàng)建鏈表并將信息存儲在二進制文件中讀取的實例代碼,需要的朋友可以參考一下2013-03-03
Linux下動靜態(tài)庫的打包與使用指南(C/C++)
c++是面向?qū)ο蟮木幊陶Z言,比較方便實現(xiàn)某些第三方庫,比如翻譯其他面向?qū)ο笳Z言的代碼,比c語言要方便的多,下面這篇文章主要給大家介紹了關(guān)于Linux下C/C++動靜態(tài)庫的打包與使用的相關(guān)資料,需要的朋友可以參考下2023-02-02
C語言?超詳細介紹與實現(xiàn)線性表中的無頭單向非循環(huán)鏈表
無頭單向非循環(huán)鏈表:結(jié)構(gòu)簡單,一般不會單獨用來存數(shù)據(jù)。實際中更多是作為其他數(shù)據(jù)結(jié)構(gòu)的子結(jié)構(gòu),如哈希桶、圖的鄰接表等等。另外這種結(jié)構(gòu)在筆試面試中出現(xiàn)很多2022-03-03

