當前位置:首頁 » 編程語言 » c語言隨機數生成整數
擴展閱讀
webinf下怎麼引入js 2023-08-31 21:54:13
堡壘機怎麼打開web 2023-08-31 21:54:11

c語言隨機數生成整數

發布時間: 2022-05-30 00:52:22

⑴ 用c語言編程如何生產隨即整數

看一下我博客里的一篇文章:

首先需要聲明的是,計算機不會產生絕對隨機的隨機數,計算機只能產生「偽隨機數」。其實絕對隨機的隨機數只是一種理想的隨機數,即使計算機怎樣發展,它也不會產生一串絕對隨機的隨機數。計算機只能生成相對的隨機數,即偽隨機數。

偽隨機數並不是假隨機數,這里的「偽」是有規律的意思,就是計算機產生的偽隨機數既是隨機的又是有規律的。怎樣理解呢?產生的偽隨機數有時遵守一定的規律,有時不遵守任何規律;偽隨機數有一部分遵守一定的規律;另一部分不遵守任何規律。比如「世上沒有兩片形狀完全相同的樹葉」,這正是點到了事物的特性,即隨機性,但是每種樹的葉子都有近似的形狀,這正是事物的共性,即規律性。從這個角度講,你大概就會接受這樣的事實了:計算機只能產生偽隨機數而不能產生絕對隨機的隨機數。

那麼計算機中隨機數是怎樣產生的呢?有人可能會說,隨機數是由「隨機種子」產生的。沒錯,隨機種子是用來產生隨機數的一個數,在計算機中,這樣的一個「隨機種子」是一個無符號整形數。那麼隨機種子是從哪裡獲得的呢?

下面看這樣一個C程序:

//rand01.c
#include<dos.h>

static unsigned int RAND_SEED;

unsigned int random(void)
{
RAND_SEED=(RAND_SEED*123+59)%65536;
return(RAND_SEED);
}

void random_start(void)
{
int temp[2];
movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);
RAND_SEED=temp[0];
}

main()
{
unsigned int i,n;
random_start();
for(i=0;i<10;i++)
printf("%u\t",random());
printf("\n");
}

這個程序(rand01.c)完整地闡述了隨機數產生的過程:
首先,主程序調用random_start()方法,random_start()方法中的這一句我很感興趣:

movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);

這個函數用來移動內存數據,其中FP_SEG(far pointer to segment)是取temp數組段地址的函數,FP_OFF(far pointer to offset)是取temp數組相對地址的函數,movedata函數的作用是把位於0040:006CH存儲單元中的雙字放到數組temp的聲明的兩個存儲單元中。這樣可以通過temp數組把0040:006CH處的一個16位的數送給RAND_SEED。

random用來根據隨機種子RAND_SEED的值計算得出隨機數,其中這一句:

RAND_SEED=(RAND_SEED*123+59)%65536;

是用來計算隨機數的方法,隨機數的計算方法在不同的計算機中是不同的,即使在相同的計算機中安裝的不同的操作系統中也是不同的。我在linux和windows下分別試過,相同的隨機種子在這兩種操作系統中生成的隨機數是不同的,這說明它們的計算方法不同。

現在,我們明白隨機種子是從哪兒獲得的,而且知道隨機數是怎樣通過隨機種子計算出來的了。那麼,隨機種子為什麼要在內存的0040:006CH處取?0040:006CH處存放的是什麼?

學過《計算機組成原理與介面技術》這門課的人可能會記得在編制ROM BIOS時鍾中斷服務程序時會用到Intel 8253定時/計數器,它與Intel 8259中斷晶元的通信使得中斷服務程序得以運轉,主板每秒產生的18.2次中斷正是處理器根據定時/記數器值控制中斷晶元產生的。在我們計算機的主機板上都會有這樣一個定時/記數器用來計算當前系統時間,每過一個時鍾信號周期都會使記數器加一,而這個記數器的值存放在哪兒呢?沒錯,就在內存的0040:006CH處,其實這一段內存空間是這樣定義的:

TIMER_LOW DW ? ;地址為 0040:006CH
TIMER_HIGH DW ? ;地址為 0040:006EH
TIMER_OFT DB ? ;地址為 0040:0070H

時鍾中斷服務程序中,每當TIMER_LOW轉滿時,此時,記數器也會轉滿,記數器的值歸零,即TIMER_LOW處的16位二進制歸零,而TIMER_HIGH加一。rand01.c中的

movedata(0x0040,0x006c,FP_SEG(temp),FP_OFF(temp),4);

正是把TIMER_LOW和TIMER_HIGH兩個16位二進制數放進temp數組,再送往RAND_SEED,從而獲得了「隨機種子」。

現在,可以確定的一點是,隨機種子來自系統時鍾,確切地說,是來自計算機主板上的定時/計數器在內存中的記數值。這樣,我們總結一下前面的分析,並討論一下這些結論在程序中的應用:

1.隨機數是由隨機種子根據一定的計算方法計算出來的數值。所以,只要計算方法一定,隨機種子一定,那麼產生的隨機數就不會變。

看下面這個C++程序:

//rand02.cpp
#include <iostream>
#include <ctime>
using namespace std;

int main()
{
unsigned int seed=5;
srand(seed);
unsigned int r=rand();
cout<<r<<endl;
}

在相同的平台環境下,編譯生成exe後,每次運行它,顯示的隨機數都是一樣的。這是因為在相同的編譯平台環境下,由隨機種子生成隨機數的計算方法都是一樣的,再加上隨機種子一樣,所以產生的隨機數就是一樣的。

2.只要用戶或第三方不設置隨機種子,那麼在默認情況下隨機種子來自系統時鍾(即定時/計數器的值)

看下面這個C++程序:

//rand03.cpp
#include <iostream>
#include <ctime>
using namespace std;

int main()
{
srand((unsigned)time(NULL));
unsigned int r=rand();
cout<<r<<endl;
return 0;
}

這里用戶和其他程序沒有設定隨機種子,則使用系統定時/計數器的值做為隨機種子,所以,在相同的平台環境下,編譯生成exe後,每次運行它,顯示的隨機數會是偽隨機數,即每次運行顯示的結果會有不同。

3.建議:如果想在一個程序中生成隨機數序列,需要至多在生成隨機數之前設置一次隨機種子。

看下面這個用來生成一個隨機字元串的C++程序:

//rand04.cpp
#include<iostream>
#include<time.h>
using namespace std;
int main()
{
int rNum,m=20;
char *ch=new char[m];

for ( int i = 0; i<m; i++ ){
//大家看到了,隨機種子會隨著for循環在程序中設置多次
srand((unsigned)time(NULL));
rNum=1+(int)((rand()/(double)RAND_MAX)*36); //求隨機值
switch (rNum){
case 1: ch[i]='a';
break ;
case 2: ch[i]='b';
break ;
case 3: ch[i]='c';
break ;
case 4: ch[i]='d';
break ;
case 5: ch[i]='e';
break ;
case 6: ch[i]='f';
break ;
case 7: ch[i]='g';
break ;
case 8: ch[i]='h';
break ;
case 9: ch[i]='i';
break ;
case 10: ch[i]='j';
break ;
case 11: ch[i]='k';
break ;
case 12: ch[i]='l';
break ;
case 13: ch[i]='m';
break ;
case 14: ch[i]='n';
break ;
case 15: ch[i]='o';
break ;
case 16: ch[i]='p';
break ;
case 17: ch[i]='q';
break ;
case 18: ch[i]='r';
break ;
case 19: ch[i]='s';
break ;
case 20: ch[i]='t';
break ;
case 21: ch[i]='u';
break ;
case 22: ch[i]='v';
break ;
case 23: ch[i]='w';
break ;
case 24: ch[i]='x';
break ;
case 25: ch[i]='y';
break ;
case 26: ch[i]='z';
break ;
case 27:ch[i]='0';
break;
case 28:ch[i]='1';
break;
case 29:ch[i]='2';
break;
case 30:ch[i]='3';
break;
case 31:ch[i]='4';
break;
case 32:ch[i]='5';
break;
case 33:ch[i]='6';
break;
case 34:ch[i]='7';
break;
case 35:ch[i]='8';
break;
case 36:ch[i]='9';
break;
}//end of switch
cout<<ch[i];
}//end of for loop

cout<<endl;
return 0;
}

而運行結果顯示的隨機字元串的每一個字元都是一樣的,也就是說生成的字元序列不隨機,所以我們需要把srand((unsigned)time(NULL)); 從for循環中移出放在for語句前面,這樣可以生成隨機的字元序列,而且每次運行生成的字元序列會不同(呵呵,也有可能相同,不過出現這種情況的幾率太小了)。
如果你把srand((unsigned)time(NULL));改成srand(2);這樣雖然在一次運行中產生的字元序列是隨機的,但是每次運行時產生的隨機字元序列串是相同的。把srand這一句從程序中去掉也是這樣。

此外,你可能會遇到這種情況,在使用timer控制項編製程序的時候會發現用相同的時間間隔生成的一組隨機數會顯得有規律,而由用戶按鍵command事件產生的一組隨機數卻顯得比較隨機,為什麼?根據我們上面的分析,你可以很快想出答案。這是因為timer是由計算機時鍾記數器精確控制時間間隔的控制項,時間間隔相同,記數器前後的值之差相同,這樣時鍾取值就是呈線性規律的,所以隨機種子是呈線性規律的,生成的隨機數也是有規律的。而用戶按鍵事件產生隨機數確實更呈現隨機性,因為事件是由人按鍵引起的,而人不能保證嚴格的按鍵時間間隔,即使嚴格地去做,也不可能完全精確做到,只要時間間隔相差一微秒,記數器前後的值之差就不相同了,隨機種子的變化就失去了線性規律,那麼生成的隨機數就更沒有規律了,所以這樣生成的一組隨機數更隨機。這讓我想到了各種晚會的抽獎程序,如果用人來按鍵產生幸運觀眾的話,那就會很好的實現隨機性原則,結果就會更公正。

最後,我總結兩個要點:
1.計算機的偽隨機數是由隨機種子根據一定的計算方法計算出來的數值。所以,只要計算方法一定,隨機種子一定,那麼產生的隨機數就是固定的。
2.只要用戶或第三方不設置隨機種子,那麼在默認情況下隨機種子來自系統時鍾。

⑵ 怎麼用C語言生成隨機數

假設要生成的隨機數是大於等於20且小於等於100的整數

#include<stdio.h>
#include<time.h>
#include<stdlib.h>
voidmain(){inta,b,x;
a=20;b=100;
srand((unsignedint)time(NULL));//用當前時間生成一個隨機數種子
x=rand()%(b-a+1)+a;
printf("得到一個隨機數:%d ",x);
}

⑶ C語言隨機整數編程問題

int rand_init(int a,int b)
{ return (rand()%(b-a+1)+a);
}

主函數 初始化 隨機數

自定義函數 里 產生 隨機數

⑷ c語言生成10個不重復的隨機整數,並輸出

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

#defineelemTypeint/*元素類型*/
#defineLEN100/*數組長度上限*/

/*生成n項min~max范圍的隨機數並存入數組randArr*/
voidrandomArray(elemTyperandArr[LEN],intn,elemTypemin,elemTypemax){
inti;
srand((unsigned)time(NULL));/*用時間做種,每次產生隨機數不一樣*/
for(i=0;i<n;i++)
randArr[i]=rand(NULL)%(max-min+1)+min;/*產生min~max的隨機數*/
}

/*列印數組*/
voidprintArr(elemTypearr[],intlen){
inti;
for(i=0;i<len;i++)
printf("%d ",arr[i]);
putchar(' ');
}

intmain(void){
elemTypearr[LEN];
intlen=10;/*10個隨機數*/

randomArray(arr,len,1,50);/*隨機生成數組內容*/
printArr(arr,len);
putchar(' ');

getch();/*屏幕暫留*/
return0;
}

運行結果

⑸ 如何用C語言隨機產生一個三位整數

思路:分別產生個、十、百位上的隨機數,依次組合在一起
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
int
main()
{
int
i,tmp;num=0;
srand((unsigned)time(NULL));//初始化隨即種子
tmp=rand()%10;
//產生個位上的隨機數
num=tmp;
tmp=rand()%10;
//生成十位上的隨機數
num=num+tmp*10;
tmp=rand()%10;
//生成百位上的隨機數
num=num+tmp*100;
printf("隨機數(3位):%d\n",num);
return
0;
}

⑹ c語言生成10個隨機整數,並對隨機數進行冒泡和快速排序。有講解更好,純新手。

終於寫完了...累死了,不過我得說一句,你這個分太少,一般不會有人像我這么無聊的..呵呵

#include
#include
#include
#define Recordtype int
void (Recordtype s[], Recordtype d[], int n);
/************************************************************************/
/* 直接插入法 */
/************************************************************************/
int cmpTforIs = 0;//記錄插入法的比較次數
int ChgTforIs = 0;//記錄插入法的交換次數
void InsertSort(Recordtype data[], int n);

/************************************************************************/
/* 折半插入法 */
/************************************************************************/
int cmpTforBinarys = 0;//記錄冒泡的比較次數
int ChgTforBinarys = 0;//記錄冒泡的交換次數
void BinarySearchInsertion(int numbers[], const int n);
/************************************************************************/
/* 冒泡法 */
/************************************************************************/
int cmpTforBs = 0;//記錄冒泡的比較次數
int ChgTforBs = 0;//記錄冒泡的交換次數
void Bubsort(Recordtype *start, Recordtype *end);
/************************************************************************/
/* 快排 */
/************************************************************************/
int cmpTforQs = 0;//記錄快排的比較次數
int ChgTforQs = 0;//記錄快排的交換次數
int quickPass(int start, int last, Recordtype record[]);
int quickSort(int start, int last, Recordtype record[]);
int main()
{
Recordtype Data[100];
Recordtype D[100];
srand(time(NULL));
printf("the rand 100 numbers are:\n");
for (int i=0; i<100; i++)
{
D[i] = rand()%1000;//便於觀察,每次產生1000內的整數
printf("%d ", D[i]);
}
printf("\n\n\n");

(D, Data, 100);
BinarySearchInsertion(Data, 100);
printf("折半插入法的比較次數為%d,交換次數為%d\n", cmpTforBinarys, ChgTforBinarys);

(D, Data, 100);
InsertSort(Data, 100);
printf("直接插入法的比較次數為%d,交換次數為%d\n", cmpTforIs, ChgTforIs);

(D, Data, 100);
Bubsort(&Data[0], &Data[99]);
printf("冒泡法的比較次數為%d,交換次數為%d\n", cmpTforBs, ChgTforBs);

(D, Data, 100);
quickSort(0, 99, Data);
printf("快排的比較次數為%d,交換次數為%d\n", cmpTforQs, ChgTforQs);

printf("排序後的序列為\n");//你可以這塊放在任意排序完畢的語句後面,檢查排序的正確性
for (i=0; i<100; i++)
{
printf("%d ", Data[i]);
}
return 0;
}
void (Recordtype s[], Recordtype d[], int n)
{
for (int i = 0; i<n; i++)
{
d[i] = s[i];
}
}

void BinarySearchInsertion(int numbers[], const int n)
{
int middle=0;
for(int i = 1; i < n; i++)
{
int low = 0 ;
int high = i-1 ;
int temp = numbers[i] ;
while(low <= high)
{
cmpTforBinarys++;
middle = (low + high) / 2 ;
if(temp < numbers[middle])
{
high = middle - 1 ;
}
else
low = middle + 1 ;
}
for(int k = i ; k >middle; k--) //K>middle不能錯
{
ChgTforBinarys++;
numbers[k] = numbers[k-1 ] ;
}
ChgTforBinarys++;
numbers[low] = temp ; //此處用 numbers[high+1] = temp ;也可
} //賦值語句不能弄錯numbers[low]=
}

void InsertSort(Recordtype data[], int n)
{
for (int i = 1; i< n; i++)
{
int temp = data[i];
for(int j = i; j>0 && temp<data[j-1]; --j)
{
ChgTforIs++;
cmpTforIs++;
data[j] = data[j-1];
}
data[j] =temp;
}
}

void Bubsort(Recordtype *start, Recordtype *end)
{
int num = end - start + 1;
Recordtype temp;
int i, j;
Recordtype *a = start;
for (i = 0; i<num; i++)
{
for (j = 0; j<num-i; j++)
{
cmpTforBs++;
if (*(a+j-1) > *(a+j))
{
ChgTforBs++;
temp = *(a+j-1);
*(a+j-1) = *(a+j);
*(a+j) = temp;
}
}
}
}

int quickPass(int start, int last, Recordtype record[])
{
int s = start, l = last;
int temp = record[s];
while (s < l)
{
while (s<l && temp <= record[l] )
{
l--;
cmpTforQs++;
}

if (s<l)
{
record[s++] = record[l];
ChgTforQs++;
}

while (s= record[s])
{
s++;
cmpTforQs++;
}
if (s<l)
{
record[l--] = record[s];
ChgTforQs++;
}
}
record[s] = temp;
ChgTforQs++;
return s;
}
int quickSort(int start, int last, Recordtype record[])
{
int pos = 0;
if (start < last)
{
pos = quickPass(start, last, record);
quickSort(start, pos-1, record);
quickSort(pos+1, last, record);
}
return 0;
}

⑺ C語言如何編程產生隨機數

1、首先打開Visual stdio 2019,依次點擊文件,新建,項目新建以一個空白的項目:

⑻ c語言中如何生成1個0到1的隨機數

C語言中生成1個0到1的隨機數可以執行語句:float b=rand()/(RAND_MAX+1.0);

解析:

標准C庫中函數rand()可以生成0~RAND_MAX之間的一個隨機數,其中RAND_MAX 是stdlib.h 中定義的一個整數,它與系統有關。rand()函數沒有輸入參數,直接通過表達式rand()來引用;

用函數rand取得的隨機數除以(RAND_MAX+1.0),即可確保得到的結果在0到1之間。ISO IEC 9899 2011 (C11)標准中未規定 RAND_MAX 的具體數值。但該標准規定了RAND_MAX 的值應至少為32767。編程的時候,不應該對 RAND_MAX 的具體數值做任何假設。

(8)c語言隨機數生成整數擴展閱讀:

相關說明:

1、因為rand()函數是按指定的順序來產生整數,因此每次執行上面的語句都列印相同的兩個值,所以說C語言的隨機並不是真正意義上的隨機。

2、為了使程序在每次執行時都能生成一個新序列的隨機值,我們通常通過為隨機數生成器提供一粒新的隨機種子。函數 srand()(來自stdlib.h)可以為隨機數生成器播散種子。只要種子不同rand()函數就會產生不同的隨機數序列。srand()稱為隨機數生成器的初始化器。

3、隨機種子(Random Seed)是計算機專業術語,一種以隨機數作為對象的以真隨機數(種子)為初始條件的隨機數。一般計算機的隨機數都是偽隨機數,以一個真隨機數(種子)作為初始條件,然後用一定的演算法不停迭代產生隨機數。

⑼ 在C語言編程中,如何實現讓電腦隨機輸出一1~9的整數

c語言中取得偽隨機數主要使用srand()和rand()這兩個函數.
rand()函數會返回一個偽隨機數,但是這是通過一種數學公式推算出來的,得到的隨機數分布太集中,這時候要使用srand()函數來設定產生隨機數的種子,一般採用當前時間作為種子,這樣可以得到分布比較均勻的偽隨機數。
rand(),srand()函數位於stdlib.h文件中,取得時間的time()函數位於time.h文件中。隨機數測試如下:
#i
nclude
<stdio.h>
#i
nclude
<stdlib.h>
#i
nclude<time.h>
void
main()
{
int
results[10];/*用於保存隨機數產生的結果*/
int
i=0;
srand((int)time(0));/*設定種子*/
for(i=0;i<10;i++)
{
results[i]=0;
}
for(i=0;i<10000;i++)
{
(results[rand()%10])++;/*取一萬次隨機數,使用求余運算符使得最後取得的隨機數小於10*/
}
for(i=0;i<1
0;i++)
{
printf("
%d
%d
\n",i,results[i]);/*輸出0-9之間的隨機數出現的次數*/
}
}
經多次運行試驗,產生的隨機數比較均勻

⑽ 怎麼用C++編寫一個rand()函數,功能上是產生10個0-100之間的隨機整數

需要准備的材料分別有:電腦、C語言編譯器。

1、首先,打開C語言編譯器,新建一個初始.cpp文件,例如:test.cpp。

(10)c語言隨機數生成整數擴展閱讀:

但是,要注意的是所謂的「偽隨機數」指的並不是假的隨機數。其實絕對的隨機數只是一種理想狀態的隨機數,計算機只能生成相對的隨機數即偽隨機數。計算機生 成的偽隨機數既是隨機的又是有規律的 —— 一部份遵守一定的規律。

一部份則不遵守任何規律。比如「世上沒有兩片形狀完全相同的樹葉」,這體現到了事物的特性 —— 差異性;但是每種樹的葉子都有近似的形狀。

這正是事物的共性 —— 規律性。從這個角度講,我們就可以接受這樣的事實了:計算機只能產生偽隨機數而不是絕對的隨機數。

系統在調用rand()之前都會自動調用srand(),如果用戶在rand()之前曾調用過srand()給參數seed指定了一個值。

那麼 rand()就會將seed的值作為產生偽隨機數的初始值;而如果用戶在rand()前沒有調用過srand(),那麼系統默認將1作為偽隨機數的初始 值。如果給了一個定值,那麼每次rand()產生的隨機數序列都是一樣的。

所以為了避免上述情況的發生通常用srand((unsigned)time(0))或者srand((unsigned)time(NULL))來 產生種子。如果仍然覺得時間間隔太小。

可以在(unsigned)time(0)或者(unsigned)time(NULL)後面乘上某個合適的整數。 例如,srand((unsigned)time(NULL)*10)