1. 程式人生 > >生成隨機數函式

生成隨機數函式

 前幾天,寫了一個猜數字的遊戲,遊戲開始在系統內部先生成一個隨機數字,然後不斷的去猜數字,和這個數字進行比較。在我看來這個遊戲最關鍵的核心語句就是生成隨機數的語句,在寫了這個程式之後,我對隨機數又有了新的認識,今天我就來跟大家說一下,我自己對隨機數的一些新認識。

  

這是學過c語言的常用的生成隨機數的語句,輸入之後發現,rand劃了波浪線,是因為,這個函式需要的標頭檔案,你並沒有寫出來。#include<stdlib.h>,寫上之後就沒有問題了。

 

 為了方便給大家截圖我有加了getchar()語句,大家看這是生成的一個隨機數字,生成之後輸出結果是41

 

之後我有對整個程式各個地方做了大大小小的更改,發現,無論你改了什麼到最後你的

rand這個隨機函式所生成的數字永遠是41,甚至我已經將vs關掉重新開啟這個程式,發現生成的還是41

  那問題來了,不是說rand的作用是生成一個隨機數麼,為什麼他這麼多次一直生成41

  因為,實際rand這個函式生成的數,其實是一個偽隨機數,他並不是真正意義上的隨機。rand函式在呼叫的時候,他會需要srand這個函式給他一個種子,他會通過得到的這個種子來生成一個隨機數字,如果你程式在呼叫rand之前並沒有呼叫srand函式,那麼程式會自動給你呼叫srand函式,然後獲得一個種子,從而rand通過這個種子來獲得隨機數字,然而當你程式呼叫過一次srand後系統就不再會給你呼叫這個函式,你的種子也就不會在有所更改,所以

rand一直在通過第一次獲得的種子來計算你的隨機值,所以你的隨機值無論怎麼樣的出來都和第一次的相同。

  如果這樣的話,你的遊戲就變成了一次性的遊戲,每次都是那個數字,他還有什麼存在的意義,那怎麼才能獲得一個真正的隨機數呢?

  所以就有了srand((unsigned int)time(NULL));srand函式,由你來每次呼叫這個函式,這樣每次呼叫他給rand的種子都不一樣,那你的rand獲得的隨機數每次也都不一樣了。

int num = 0;

int n = 0;

srand((unsigned int)time(NULL));

num = rand() % 100 + 1;

printf("請猜一個1-100之間的數字\n"

);

scanf("%d", &n);

while (n != num)

{

if (n > num)

{

printf("猜大了,請重新輸入\n");

}

if (n < num)

{

printf("猜小了,請重新輸入\n");

}

scanf("%d", &n);

}

printf("猜測正確\n");

  這是我寫的猜數字遊戲的遊戲部分,核心語句。srand((unsigned int)time(NULL));到底系統怎麼樣每次才能獲得不一樣的一個變數呢?很多人自然就想到了時間,時間是永遠不會存在兩個相同的時間,所以根據你的系統時間來生成一個隨機數是最好不過的了。這裡time實際上也是一個c語言的函式,它是用來獲得時間的函式,

 

這是c++對time函式的一個定義,他不能直接使用這個函式的返回值,必須依賴於其他元素來呼叫這個物件,變成一個可移植的型別,所以,這裡實際上是srand函式呼叫了time函式time函式返回給了一個srand值,然後srand通過這個值來生成一個種子,正因為time一直在變化,時間一直在變化,他獲得的值就不同,有人問,那我今天的早上八點整和明天的早上八點整同時執行這個程式生成的隨機數字一樣嗎?不一樣,這個的時間,指的是從1970年1月1日0點0分0秒開始到你呼叫函式這一刻的時間,他是一直在變化的。unsigned int)time(NULL)這句話的意思就是將time得到的值轉化為一個unsigned int型,我嘗試了改為int型之後程式也可以正常執行,unsigned的意思就是沒有符號,這裡將time的值轉換成了一個沒有符號的整型,我感覺應該1970年以後得到的數字都是正數吧,除非你的系統時間設定為了1970年之後就要加unsigned了吧,明天有時間準備嘗試一下這個事情,如果有結果了我會及時說出來的。

  所以,大家如果以後要是想要生成一個隨機數字,那在每次呼叫rand之前都一定要記著手動呼叫一下srand函式,變數要是時間這樣的話才會最大程度的保證你每次生成的都是一個不相同的隨機數字。

  還有就是,如果大家要寫這個srand函式的話,因為你呼叫了time函式所以大家一定要記著加上time函式的標頭檔案#include<time.h>。