1. 程式人生 > 其它 >C語言——隨機數函式

C語言——隨機數函式

技術標籤:c語言

ANSI C庫提供了rand()函式生成隨機數。生成隨機數有多種演算法,ANSC I允許C實現針對特定機器使用最佳演算法,在不同系統中生成相同的隨機數。實際上,rand()生成的是偽隨機數,即可預測接下來要生成的數字,但數字在其取值範圍內均勻分佈。

rand()函式
包含在“stdlib.h”標頭檔案中。

函式原型 int rand(void)

為了掩飾程式內部執行的情況,下面的程式碼並不是編譯器內建的函式。

static unsigned long int next = 1;
unsigned int rand1(void)
{
	next = next * 1103515245
+ 12345; //魔術公式 return (unsigned int)(next / 65536) % 32678; }

函式開始於一個“種子”數字,該數字被函式使用後,生成一個新數,新數又成為函式的種子,供下一次使用,以此類推。不難發現,隨機數函式並不是隨機的,只不過這個函式的週期特別的大,模擬隨機的效果特別好,這也是魔術公式的神奇之處。
直接使用的話函式會生成0-RAND_MAX(32767)之間的隨機數,要想生成指定區間的隨機數,可以使用求餘運算。比如生成[a,b]之間的隨機數,則rand()%(b-a+1)+a,因為計算機的區間都是左開右閉的。
值得注意的是,多次執行程式後,就會發現,產生的隨機數完全相同,這也是偽隨機的一個表現,因為種子的初始值相同都是1。

如何讓每次執行產生不同的隨機數呢?很明顯,只需要重置種子就可以解決這個問題。ANSI C庫為我們提供了srand()函式。

srand()函式
包含在“stdlib.h”標頭檔案中。

函式原型 void srand(unsigned int seed)

unsigned long int next = 1;
unsigned int rand2(void)
{
	next = next * 1103515245 + 12345;
	return (unsigned int)(next / 65536) % 32678;
}

void srand1(unsigned int seed)
{
	next =
seed; }

因為next為內部連結的檔案作用域靜態變數,所以rand2()和srand1()都可以使用它,但是其他檔案無法訪問。
但是如果每次使用隨機數函式都要人為對種子賦予新值來獲得不同的隨機數的話,顯然不太方便,所以C允許訪問一些可變的量,可以用這些值初始化種子值。

ANSI C庫提供了一個time()函式。

time()函式
包含在“time.h”標頭檔案中。

函式原型 time_t time(time_t *timer)

time()函式用來返回系統時間,返回值是一個可進行運算的型別,並且其值隨著時間變化而變化。time()返回值型別是time_t,具體型別與系統有關。但這不重要,我們可以用強制型別轉換。
timer=NULL時得到當前日曆時間(從1970-01-01 00:00:00到現在的秒數),timer=時間數值時,用於設定日曆時間。如果timer不為空,則返回值也儲存在變數timer中。
time()函式有兩種使用方法:
(1)time(NULL)或time(0);
(2)time(&t);
將變數t的地址作為實參傳遞給time()函式,函式自動把結果傳遞給t,不需要額外的賦值語句。

#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#define N 10
int main()
{
	//產生十個min到max間的隨機數
	int i, max, min;
	scanf("%d%d", &min, &max);
	srand((unsigned int)time(0));
	for (i = 0;i < N;i++)
	{
		printf("%d ", rand() % (max - min + 1) + min);
	}
	return 0;
}