生成隨機(jī)數(shù)的概念
??生成隨機(jī)數(shù)是指按照一定的規(guī)律,產(chǎn)生一些看似無規(guī)律的數(shù)字序列。在計(jì)算機(jī)中,通常使用隨機(jī)數(shù)生成器來生成隨機(jī)數(shù)。隨機(jī)數(shù)生成器可以分為真隨機(jī)數(shù)生成器和偽隨機(jī)數(shù)生成器兩種。真隨機(jī)數(shù)生成器是利用物理現(xiàn)象產(chǎn)生的隨機(jī)事件(如放射性衰變)來生成隨機(jī)數(shù)。而偽隨機(jī)數(shù)生成器是利用算法產(chǎn)生的數(shù)字序列,雖然看似無規(guī)律,但實(shí)際上是可以預(yù)測(cè)的。
??在計(jì)算機(jī)中,通常使用偽隨機(jī)數(shù)生成器來生成隨機(jī)數(shù)。偽隨機(jī)數(shù)生成器通常由一個(gè)種子值和一個(gè)算法組成。種子值是生成隨機(jī)數(shù)的起始值,而算法則是根據(jù)種子值和一些數(shù)學(xué)運(yùn)算來產(chǎn)生下一個(gè)隨機(jī)數(shù)。為了讓生成的隨機(jī)數(shù)更加隨機(jī),通常會(huì)將種子值設(shè)置為當(dāng)前的時(shí)間戳,以確保每次運(yùn)行程序時(shí)生成的隨機(jī)數(shù)都不同。
相關(guān)函數(shù)介紹
??由于在生成隨機(jī)數(shù)的時(shí)候會(huì)使用到某些函數(shù),接下來先進(jìn)行補(bǔ)充。
time()函數(shù)
??C語言的time()函數(shù)原型為:
time_t time(time_t *t);
??其中,time_t是C語言標(biāo)準(zhǔn)庫中的一種時(shí)間類型,time()函數(shù)的返回值類型為time_t。該函數(shù)的作用是獲取當(dāng)前時(shí)間的秒數(shù),并將其返回。如果將一個(gè)time_t類型的指針傳遞給該函數(shù),它會(huì)將當(dāng)前時(shí)間的秒數(shù)存儲(chǔ)在該指針?biāo)赶虻淖兞恐小?/p>
??以下是一個(gè)簡單的示例:
#include <stdio.h>
#include <time.h>
int main(int argc, char const *argv[])
{
time_t time_value;
time_value = time(NULL);
printf("time_value:%ld\n", time_value);
return 0;
}
??在Linux中的運(yùn)行結(jié)果為:
??該程序輸出的是當(dāng)前時(shí)間的秒數(shù)。如果想要將時(shí)間戳轉(zhuǎn)換為其他形式的時(shí)間表示,可以使用C語言標(biāo)準(zhǔn)庫中的其他函數(shù),例如gmtime()、localtime()等。
?? time(NULL)
函數(shù)獲取的是從1970年1月1日0時(shí)0分0秒開始到當(dāng)前時(shí)刻的秒數(shù),即Unix時(shí)間戳。Unix時(shí)間戳是計(jì)算機(jī)領(lǐng)域中常用的時(shí)間表示方法之一,它是以UTC時(shí)間為基準(zhǔn),以秒為單位計(jì)算的時(shí)間戳,可以方便地進(jìn)行時(shí)間計(jì)算和比較。
??需要注意的是,由于time(NULL)獲取的是當(dāng)前時(shí)刻的秒數(shù),因此它的返回值是一個(gè)動(dòng)態(tài)變化的值,每次調(diào)用都會(huì)返回不同的值。如果需要在程序中多次使用當(dāng)前時(shí)間,應(yīng)該將time(NULL)的返回值保存在一個(gè)變量中,而不是多次調(diào)用該函數(shù)。
srand()函數(shù)
??srand()函數(shù)是C語言標(biāo)準(zhǔn)庫中的一個(gè)函數(shù),用于設(shè)置隨機(jī)數(shù)生成器的種子。它的原型如下:
void srand(unsigned int seed);
??其中,seed是一個(gè)無符號(hào)整數(shù),用于指定隨機(jī)數(shù)生成器的種子。調(diào)用srand()函數(shù)后,隨機(jī)數(shù)生成器將以seed作為起始值,生成一系列隨機(jī)數(shù)。
??需要注意的是,如果不調(diào)用srand()函數(shù),隨機(jī)數(shù)生成器將使用一個(gè)默認(rèn)的種子。由于默認(rèn)種子通常是根據(jù)系統(tǒng)時(shí)間來生成的,因此每次運(yùn)行程序時(shí),隨機(jī)數(shù)生成器都會(huì)生成不同的隨機(jī)數(shù)序列。
??以下是一個(gè)簡單的示例:
#include <stdio.h>
#include <time.h>
#include <stdlib.h>
int main(int argc, char const *argv[])
{
int r;
// 設(shè)置隨機(jī)數(shù)的種子
srand(time(NULL));
for (int i = 0; i < 5; i++)
{
// 生成隨機(jī)數(shù)
r = rand();
printf("%d\n", r);
}
return 0;
}
??在Linux中得到的運(yùn)行結(jié)果為:
??該程序使用time()函數(shù)獲取當(dāng)前時(shí)間的秒數(shù)作為種子,調(diào)用srand()函數(shù)設(shè)置隨機(jī)數(shù)生成器的種子,然后調(diào)用rand()函數(shù)生成一系列隨機(jī)數(shù)。由于種子是基于時(shí)間的,因此每次運(yùn)行程序時(shí),生成的隨機(jī)數(shù)序列都是不同的。
srandom()函數(shù)
??srandom()
函數(shù)是C語言中用于初始化隨機(jī)數(shù)生成器的函數(shù)。它的作用是設(shè)置一個(gè)種子,使得隨機(jī)數(shù)生成器能夠產(chǎn)生不同的隨機(jī)數(shù)序列。它的原型如下:
void srandom(unsigned int seed);
??srandom()
函數(shù)需要一個(gè)unsigned int
類型的參數(shù)作為種子,這個(gè)種子可以是任意值,但是推薦使用當(dāng)前時(shí)間作為種子,以保證每次程序運(yùn)行時(shí)生成的隨機(jī)數(shù)序列不同。使用srandom()
函數(shù)之后,每次調(diào)用random()
函數(shù)都會(huì)生成一個(gè)新的隨機(jī)數(shù),而且這些隨機(jī)數(shù)之間也沒有任何關(guān)聯(lián),也不會(huì)重復(fù)。
??下面是一個(gè)示例程序,演示如何使用srandom()
函數(shù)和random()
函數(shù)生成隨機(jī)數(shù):
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char const *argv[])
{
int i, r;
unsigned int seed;
srandom(seed);
for (int i = 0; i < 5; i++)
{
r = random();
printf("%d\t", r);
}
printf("\n");
return 0;
}
??在Linux中觀察到的運(yùn)行結(jié)果:
??在這個(gè)示例程序中使用time()
函數(shù)獲取當(dāng)前時(shí)間,將其轉(zhuǎn)換為unsigned int
類型的值,并作為srandom()
函數(shù)的參數(shù),以此來初始化隨機(jī)數(shù)生成器。然后使用random()
函數(shù)生成5個(gè)隨機(jī)數(shù),并將其輸出到屏幕上。由于使用了srandom()
函數(shù),每次運(yùn)行程序時(shí),生成的隨機(jī)數(shù)序列都是不同的。
??需要注意的是,在使用srandom()
函數(shù)之前,必須包含頭文件<time.h>
,否則編譯器會(huì)報(bào)錯(cuò)。
??在上文中使用了兩個(gè)函數(shù)對(duì)隨機(jī)數(shù)的種子進(jìn)行設(shè)定,但它們有何區(qū)別呢?
??srandom()
函數(shù)和srand()
函數(shù)都是C語言中用于生成隨機(jī)數(shù)的函數(shù),它們的作用是設(shè)置隨機(jī)數(shù)生成器的種子,以便產(chǎn)生不同的隨機(jī)數(shù)序列。它們的不同之處在于參數(shù)類型和取值范圍。
??srand()
函數(shù)的原型如下:
void srand(unsigned int seed);
??srand()
函數(shù)需要一個(gè)unsigned int
類型的參數(shù)作為種子,這個(gè)種子可以是任意值,但是推薦使用當(dāng)前時(shí)間作為種子,以保證每次程序運(yùn)行時(shí)生成的隨機(jī)數(shù)序列不同。在使用srand()
函數(shù)之后,每次調(diào)用rand()
函數(shù)都會(huì)生成一個(gè)新的隨機(jī)數(shù),而且這些隨機(jī)數(shù)之間也沒有任何關(guān)聯(lián),也不會(huì)重復(fù)。注意,srand()
函數(shù)的參數(shù)是一個(gè)32位無符號(hào)整數(shù),其取值范圍是0到4294967295。
??srandom()
函數(shù)的原型如下:
void srandom(unsigned int seed);
??srandom()
函數(shù)也需要一個(gè)unsigned int
類型的參數(shù)作為種子,但是和srand()
函數(shù)不同的是,srandom()
函數(shù)使用的是一個(gè)48位整數(shù)作為種子,其取值范圍更加廣泛,可以達(dá)到更高的隨機(jī)性。在使用srandom()
函數(shù)之后,每次調(diào)用random()
函數(shù)都會(huì)生成一個(gè)新的隨機(jī)數(shù),而且這些隨機(jī)數(shù)之間也沒有任何關(guān)聯(lián),也不會(huì)重復(fù)。注意,srandom()
函數(shù)的參數(shù)是一個(gè)32位無符號(hào)整數(shù),但是內(nèi)部會(huì)將其擴(kuò)展為48位整數(shù)。
??需要注意的是,srand()
函數(shù)和srandom()
函數(shù)是不可互換的,也就是說,如果在程序中使用了srandom()
函數(shù)設(shè)置了隨機(jī)數(shù)生成器的種子,那么在生成隨機(jī)數(shù)時(shí)必須使用random()
函數(shù)。同樣地,如果在程序中使用了srand()
函數(shù)設(shè)置了隨機(jī)數(shù)生成器的種子,那么在生成隨機(jī)數(shù)時(shí)必須使用rand()
函數(shù)。
random函數(shù)()
??random()
函數(shù)是C語言標(biāo)準(zhǔn)庫中用于生成隨機(jī)數(shù)的函數(shù)。它的函數(shù)原型定義在<stdlib.h>
頭文件中:
long int random(void);
??該函數(shù)返回一個(gè)長整型數(shù)值,取值范圍在0到RAND_MAX
之間(包含0和RAND_MAX
)。RAND_MAX
是一個(gè)常量,它表示隨機(jī)數(shù)的最大值,其值至少為32767。
??在調(diào)用random()
函數(shù)之前,需要先使用srandom()
函數(shù)來設(shè)置隨機(jī)數(shù)種子。如果沒有調(diào)用srandom()
函數(shù),那么random()
函數(shù)每次都會(huì)使用默認(rèn)的隨機(jī)數(shù)種子,生成的隨機(jī)數(shù)序列就會(huì)相同。
??random()
函數(shù)的實(shí)現(xiàn)使用了一個(gè)名為__random_data
的結(jié)構(gòu)體來存儲(chǔ)隨機(jī)數(shù)生成器的狀態(tài)。這個(gè)結(jié)構(gòu)體包括了一些用于生成隨機(jī)數(shù)的參數(shù),比如隨機(jī)數(shù)種子、隨機(jī)數(shù)生成器的狀態(tài)等等。在random()
函數(shù)中,首先調(diào)用__random_getstate()
函數(shù)獲取隨機(jī)數(shù)生成器的狀態(tài),然后再調(diào)用__random_r()
函數(shù)生成一個(gè)隨機(jī)數(shù),并返回該隨機(jī)數(shù)。
??需要注意的是,random()
函數(shù)不是真正的隨機(jī)數(shù)生成器,它只是生成一個(gè)偽隨機(jī)數(shù)。生成的隨機(jī)數(shù)是依據(jù)隨機(jī)數(shù)生成器的狀態(tài)(種子)和算法計(jì)算得到的,因此在給定相同的種子和算法的情況下,random()
函數(shù)生成的隨機(jī)數(shù)序列是固定的。如果需要更高質(zhì)量的隨機(jī)數(shù),可以使用其他的隨機(jī)數(shù)生成器庫,例如OpenSSL、libgcrypt等。
getpid()函數(shù)
??getpid()
函數(shù)是一個(gè)用于獲取當(dāng)前進(jìn)程ID(Process ID)的函數(shù),它的函數(shù)原型定義在<sys/types.h>
頭文件中:
#include <sys/types.h>
#include <unistd.h>
pid_t getpid(void);
??該函數(shù)返回一個(gè)pid_t
類型的值,表示當(dāng)前進(jìn)程的ID。進(jìn)程ID是一個(gè)非負(fù)整數(shù),通常由操作系統(tǒng)分配。每個(gè)進(jìn)程都有一個(gè)唯一的進(jìn)程ID,可以用來標(biāo)識(shí)進(jìn)程。
??需要注意的是,進(jìn)程ID并不是隨機(jī)分配的,而是按照一定的規(guī)則分配的。通常情況下,進(jìn)程ID是連續(xù)的,即相鄰的進(jìn)程ID之間只相差1。但是,如果某個(gè)進(jìn)程退出,它的進(jìn)程ID可能會(huì)被其他進(jìn)程重新使用,因此不能保證進(jìn)程ID是連續(xù)的。
??下面是一個(gè)使用getpid()
函數(shù)獲取當(dāng)前進(jìn)程ID的例子:
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
pid_t pid = getpid();
printf("pid的值為:%d\n", pid);
return 0;
}
在Linux中觀察到的運(yùn)行結(jié)果為:
生成隨機(jī)數(shù)的方法
??下面是4個(gè)例子演示了不同的生成隨機(jī)數(shù)的方法。
例子1:使用rand()函數(shù)生成隨機(jī)數(shù)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char const *argv[])
{
srand(time(NULL));
int random_number = rand() % 10;
printf("得到的隨機(jī)數(shù)為:%d\n", random_number);
return 0;
}
??在Linux中的運(yùn)行結(jié)果為:
例子2:使用random函數(shù)生成隨機(jī)數(shù)
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc, char const *argv[])
{
// 初始化隨機(jī)數(shù)種子
srandom(time(NULL));
// 生成0~9之間的隨機(jī)數(shù)
int random_num = random() % 10;
printf("隨機(jī)數(shù)為:%d\n", random_num);
return 0;
}
??在Linux中的運(yùn)行結(jié)果為:
例子3:使用getpid函數(shù)生成隨機(jī)數(shù)
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
srand(getpid());
printf("隨機(jī)數(shù)為:%d\n", rand() % 10);
return 0;
}
在Linux中觀察到的運(yùn)行結(jié)果為:文章來源:http://www.zghlxwxcb.cn/news/detail-755661.html
例子4:使用/dev/random和/dev/urandom設(shè)備文件生成隨機(jī)數(shù)
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char const *argv[])
{
int random_num;
// 從/dev/random設(shè)備文件中讀取隨機(jī)數(shù)
int fd = open("/dev/random", O_RDONLY);
if (fd < 0)
{
perror("open /dev/random failed");
return -1;
}
read(fd, &random_num, sizeof(random_num));
close(fd);
printf("/dev/random生成的隨機(jī)數(shù)為:%d\n", random_num);
// 從/dev/urandom設(shè)備文件中讀取隨機(jī)數(shù)
fd = open("/dev/urandom", O_RDONLY);
if (fd < 0)
{
perror("open /dev/urandom failed");
return -1;
}
read(fd, &random_num, sizeof(random_num));
close(fd);
printf("/dev/urandom生成的隨機(jī)數(shù)為:%d\n", random_num);
return 0;
}
??在Linux中觀察到的運(yùn)行結(jié)果:
??這些例子展示了不同的生成隨機(jī)數(shù)的方法,包括使用rand函數(shù)、random函數(shù)、getpid函數(shù)以及/dev/random和/dev/urandom設(shè)備文件。在實(shí)際開發(fā)中,可以根據(jù)具體需求選擇適合的隨機(jī)數(shù)生成方法。文章來源地址http://www.zghlxwxcb.cn/news/detail-755661.html
到了這里,關(guān)于C語言中生成隨機(jī)數(shù)的方法的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!