C言語のrand()とsrand()の使い方。乱数の範囲指定・シード・応用例を図解で解説。
stdlib.h に含まれる rand() 関数で擬似乱数を生成します。「擬似」とつくのは、内部で数学的な計算式を使っているため、完全にランダムではないからです。しかし、通常の用途には十分です。
#include <stdlib.h> // rand(), srand() #include <time.h> // time() — シード用
rand() は 0 〜 RAND_MAX(通常 2147483647)の整数を返します。しかし、そのまま使うと毎回同じ順番の乱数が出てしまいます。
srand(seed) で乱数の「種」を設定すると、そこから異なる系列の乱数が生まれます。プログラムの最初に1回だけ呼びます。
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { srand(time(NULL)); // 現在時刻でシードを設定(毎回違う値) for (int i = 0; i < 5; i++) { printf("%d\n", rand()); } return 0; }
rand() はとても大きな数を返すので、剰余演算子 % で範囲を絞ります。
// 0 〜 9 の乱数 int r = rand() % 10; // 1 〜 6 の乱数(サイコロ) int dice = rand() % 6 + 1; // min 〜 max の乱数 int val = rand() % (max - min + 1) + min;
| やりたいこと | コード |
|---|---|
| 0 〜 N-1 | rand() % N |
| 1 〜 N | rand() % N + 1 |
| min 〜 max | rand() % (max - min + 1) + min |
#include <stdio.h> #include <stdlib.h> #include <time.h> int main(void) { char *hands[] = {"グー", "チョキ", "パー"}; srand(time(NULL)); int cpu = rand() % 3; // 0:グー 1:チョキ 2:パー printf("CPUの手: %s\n", hands[cpu]); return 0; }
// Fisher-Yatesシャッフル for (int i = n - 1; i > 0; i--) { int j = rand() % (i + 1); // a[i] と a[j] を交換 int tmp = a[i]; a[i] = a[j]; a[j] = tmp; }
rand() % N で生成した乱数が本当に均等に分布しているか、ヒストグラムで確認してみましょう。試行回数が増えるほど均等に近づきます。
rand()、srand()、time() が使えます。この講座の理解度をチェックしましょう!
rand() は 0 から RAND_MAX(通常32767以上)までの整数を返します。特定の範囲にするには % 演算子を使います。
srand() は乱数生成器のシードを設定します。同じシードでは同じ乱数列が生成されるため、通常 time(NULL) を使います。
rand() % 6 は 0〜5 を返すので、+1 して 1〜6 にします。rand() % 7 だと 0〜6 になってしまいます。