C語言亂數生成全攻略:rand與srand函式的實用教學與範例

1. 在C語言中產生亂數的方法:rand函式

1.1 什麼是rand函式?

rand()函式是C語言用來產生偽亂數的函式。偽亂數是根據預先定義的演算法所產生的數列,雖然不是真正隨機的亂數,但一般用途已經足夠。rand()會回傳一個範圍在0到32767之間的整數。這個範圍根據系統不同可能會有所變化,但通常是這個值。

1.2 rand函式的基本用法

要使用rand()函式,需要先引入stdlib.h。以下範例展示如何使用rand()產生亂數。

#include <stdio.h>
#include <stdlib.h>

int main(void) {
    int randomNumber = rand(); 
    printf("Generated random number: %d
", randomNumber);
    return 0;
}

執行這段程式碼後,會顯示0到32767之間的亂數。不過,這樣寫每次執行都會產生相同的亂數,這點會在後面說明。

2. 調整亂數範圍的方法

2.1 使用取餘數來限制範圍

在產生亂數時,常常需要指定某個範圍。例如,要產生1到100之間的亂數,可以對rand()的輸出使用取餘數%運算子來調整範圍。

int numberInRange = rand() % 100 + 1; // 產生1到100的亂數

在這個範例中,先用rand()的輸出對100取餘數,再加1,就能產生1到100的亂數。利用取餘數,可以很簡單地產生任意範圍的亂數。

2.2 指定範圍產生亂數

如果需要更彈性的範圍,也可以自訂函式來產生指定範圍內的亂數。以下是一個產生任意最小值與最大值範圍亂數的函式範例:

int getRandomNumber(int min, int max) {
    return rand() % (max - min + 1) + min;
}

使用這個函式時,只需像getRandomNumber(1, 100)這樣呼叫,即可產生1到100之間的亂數。

3. 使用srand函式改變亂數序列

3.1 什麼是srand函式?

如果直接使用rand()函式,每次執行程式時會得到相同的亂數序列。這是偽亂數的特性,對除錯很方便,但在實際應用需要真正的隨機時就有問題。這時可以用srand()函式設定亂數的種子(seed),改變產生的亂數序列。

3.2 srand函式的用法

srand()函式需在rand()之前呼叫,用來設定亂數種子。通常會用srand((unsigned int)time(NULL)),以目前時間作為種子。

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

int main(void) {
    srand((unsigned int)time(NULL)); // 以目前時間設定種子
    int randomNumber = rand(); 
    printf("Generated random number: %d
", randomNumber);
    return 0;
}

透過srand(),每次執行時都會產生不同的亂數序列。time(NULL)會回傳目前的時間(單位:秒),因此每次種子都不同。

4. 亂數的應用範例

4.1 在遊戲中的亂數應用

亂數在遊戲開發中非常常用,例如隨機設定角色位置、決定道具出現機率等。以下是一個擲骰子模擬的範例:

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

int main(void) {
    srand((unsigned int)time(NULL)); // 設定種子
    int diceRoll = rand() % 6 + 1; // 產生1到6的亂數
    printf("Dice roll: %d
", diceRoll);
    return 0;
}

這段程式會產生1到6的隨機數,模擬骰子的點數。使用亂數可讓遊戲更有不可預測的變化。

4.2 利用蒙地卡羅法進行模擬

亂數也可用於蒙地卡羅法這類模擬。蒙地卡羅法是利用亂數來近似求解難以解析的問題。例如可以利用亂數來近似計算圓周率 π 的值。

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

int main(void) {
    int n_trials = 1000000;
    int n_inside = 0;
    double x, y, pi;

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

    for (int i = 0; i < n_trials; i++) {
        x = (double)rand() / RAND_MAX;
        y = (double)rand() / RAND_MAX;
        if (x * x + y * y <= 1) {
            n_inside++;
        }
    }

    pi = 4.0 * n_inside / n_trials;
    printf("Approximated π: %f
", pi);

    return 0;
}

這個程式會用隨機點來近似圓周率,這就是蒙地卡羅法。rand()用來產生0到1之間的亂數,進而近似計算圓面積。

5. 使用rand和srand函式時的注意事項

5.1 理解偽亂數

C語言的rand()產生的是偽亂數,不是真正的隨機值,而是根據內部演算法計算得來。所以如果使用相同的種子,產生的亂數序列也會一樣。這對除錯很方便,但若需要完全隨機時並不適合。

5.2 常見錯誤

使用亂數時常見的錯誤有:沒用srand()設定種子,或誤解rand()的取值範圍。尤其若沒先用srand()設定種子,每次都會產生相同序列。另外,rand() % n的運用,n的設計也可能導致結果不如預期,要多加注意。

結論

C語言中的亂數生成,廣泛應用於遊戲、模擬等領域。只要熟悉rand()srand()的正確用法,就能為程式加入更多隨機與變化。歡迎參考本文內容,試著寫出自己的亂數程式!

侍エンジニア塾