広告スペース

第17回 乱数の生成

C言語のrand()とsrand()の使い方。乱数の範囲指定・シード・応用例を図解で解説。

乱数とは

乱数(ランダムな数)とは、規則性がなく予測不能な数のことです。ゲームの敵の出現位置、サイコロのシミュレーション、暗号の鍵生成など、あらゆる場面で使われます。
C言語では stdlib.h に含まれる rand() 関数で擬似乱数を生成します。「擬似」とつくのは、内部で数学的な計算式を使っているため、完全にランダムではないからです。しかし、通常の用途には十分です。

乱数に必要なヘッダ

#include <stdlib.h>   // rand(), srand()
#include <time.h>     // time() — シード用

rand() と srand()

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;
}
srand() を忘れるとどうなる?
ボタンを押して確認 →

範囲を指定して乱数を生成

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-1rand() % N
1 〜 Nrand() % N + 1
min 〜 maxrand() % (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)

// 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() が使えます。

広告スペース

関連する講座

繰り返し・配列・文字列
第16回 初等関数(math.h)
C言語のmath.hライブラリ。sqrt, sin, cos, powなど数学関数の使い方。
繰り返し・配列・文字列
第14回 繰り返し(for/while)
C言語のfor文とwhile文の使い方。ループ処理を図解で解説。
繰り返し・配列・文字列
第18回 配列
C言語の配列の宣言・初期化・アクセス方法。メモリ配置も図解。
アルゴリズム編
第30回 ソートアルゴリズム
C言語のソートアルゴリズム。バブル・選択・挿入ソートをアニメーションで可視化。
← 前の講座
第16回 初等関数(math.h)
次の講座 →
第18回 配列

確認クイズ

この講座の理解度をチェックしましょう!

Q1. rand() 関数の戻り値の範囲は?

0〜99
0〜RAND_MAX
1〜100

rand() は 0 から RAND_MAX(通常32767以上)までの整数を返します。特定の範囲にするには % 演算子を使います。

Q2. srand() の役割は?

乱数を生成する
乱数のシード(種)を設定する
乱数をソートする

srand() は乱数生成器のシードを設定します。同じシードでは同じ乱数列が生成されるため、通常 time(NULL) を使います。

Q3. 1〜6 のサイコロを作る式は?

rand() % 6
rand() % 6 + 1
rand() % 7

rand() % 6 は 0〜5 を返すので、+1 して 1〜6 にします。rand() % 7 だと 0〜6 になってしまいます。

この記事をシェア
X(Twitter)でシェア Facebookでシェア LINEで送る はてブ

この講座の理解を深めるおすすめ書籍

サイトで動きを理解し、書籍で演習量を補うと効果的です

📘
苦しんで覚えるC言語
MMGames 著
初心者向けの定番入門書。丁寧な解説で基礎を固められます。
Amazonで見る
📗
新・明解C言語 入門編
柴田望洋 著
図解が豊富で、演習問題も充実。大学の教科書としても採用多数。
Amazonで見る
📙
プログラミング言語C 第2版
B.W.カーニハン, D.M.リッチー 著
通称K&R。C言語の原典。基礎を終えた後のステップアップに最適。
Amazonで見る

※ 上記リンクはアフィリエイトリンクです。購入によりサイト運営を支援いただけます。