產生隨機數(rand()函數和srand()函數)


  有時候,我們需要隨機產生一個在某范圍的數,C/C++提供了一個庫函數rand()來產生隨機數。

函數原型:int rand(void);

功能:返回一個[0,RAND_MAX]間的隨機整數。其中RAND_MAX是定義在stdlib.h頭文件中的一個常量。

注意: rand()函數包含在頭文件stdlib.h中,要使用它必須用#include<stdlib.h>引入該頭文件;

    計算機實際上並沒有真正做到產生一個隨機數,只是在一串預先定義好的數據中選擇一個返回給函數。

 

  那么,如何得到一個在a到b的整數呢?有兩種方法:

法一:

公式:a+rand()%(b-a+1)

示例:

n=1000+rand()%9000;//隨機生成一個四位數返回給n。a+rand()%(b-a+1),四位數即1000-9999,此時a=1000,b=9999 

法二:

公式:a+rand()*(b-a+1)/RAND_MAX

示例:

n=1000+rand()*9000/RAND_MAX;//隨機生成一個四位數返回給n。a+rand()*(b-a+1)/RAND_MAX,四位數即1000-9999,此時a=1000,b=9999 

 

  當要產生多個隨機數時,rand()會重復調用產生相同的數字序列。如果想要每次執行產生的隨機數不同,就需要進行隨機初始化。因此引入srand()函數。

函數原型:void srand(unsigned seed);

功能:根據隨機數生成器的種子seed的值初始化隨機數。

 

  我們當然可以用數組和循環來設置種子的值,那么有沒有什么我們可以直接利用的一直變化的值呢?

  當然有,時間就是。我們可以借助time.h頭文件中的time(NULL)返回機器當前的時間。

函數原型:time_t time(time_t *t)

功能:返回自紀元 Epoch(1970-01-01 00:00:00 UTC)起經過的時間。當參數為空指針NULL時,返回到當前機器時間的秒數,精度為長整型ld。

注意:要使用time()函數,先要通過#include<time.h>引入time.h頭文件。

示例:

#include <stdio.h>
#include <time.h>

int main ()
{
  time_t seconds;

  seconds = time(NULL);
  printf("自 1970-01-01 起的小時數 = %ld\n", seconds/3600);
  
  return(0);
}

 

  現在,將time(NULL)作為srand()函數的隨機數產生器種子,即srand(time(NULL))就可以通過不斷變化的系統時間得到不同的隨機數。

示例:

問題描述:

隨機產生一個四位數,同時給出各位數字和。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int main()
{
    while(1)
    {
        int n,a,b,c,d,s;
        srand(time(NULL));
    //    n=1000+rand()%9000;//a+rand()%(b-a+1),四位數1000-9999,a=1000,b=9999 
        n=1000+rand()*9000/RAND_MAX;
        a=n/1000;
        b=n%1000/100;
        c=n%100/10;
        d=n%10;
        s=a+b+c+d;
        printf("%d\n",n);
        printf("s=%d\n",s);
        getchar();
    }
    return 0;
} 

運行結果:

可以看出,我們成功得到了隨機的四位數。

 

拓展問題:

1.為什么還會產生連續的相同的隨機數?

答:鍵盤按太快了,函數讀取系統時間有一定的延遲,是以秒為單位的,在1秒內按下的多個輸入均視為相同時間,隨機種子數不變,所以產生了相同的數。

 

2.1970年到現在已經過去了n秒,n是一個很大的數,是不是比rand()函數參數取的最大值RAND_MAX還大?會不會因為溢出而產生錯誤?

答:不會。在VC6中,RAND_MAX值是0x7fff,n確實比RAND_MAX大的多,即使n小於RAND_MAX,在未來也必然會有超過RAND_MAX的時刻。此時的隨機種子數seed=n mod RAND_MAX,即按RAND_MAX長度為一個周期,取余數賦值給隨機種子數seed。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM