【C言語】
乱数(rand)の基本的な使い方と注意点

結果がいつも同じ? 乱数(rand)の使い方

■乱数の種まき

●srand関数による乱数の種まきをしないと
結果がいつも同じとなる
●実務ではrand関数よりrandom関数を使う


■乱数を生成するrand関数の使い方

#include    <stdio.h>
#include    <stdlib.h>
#include    <time.h>
void 乱数の種なし(void){ 
    for(int i = 0 ;i<10;i++){
        switch (rand() % 4)		{
        case 0: printf("風");   break;			    
        case 1: printf("林");   break;
        case 2: printf("火");   break;
        case 3: printf("山");   break;
        }
    }
    printf("<-種なし:何回実行しても同じ結果になる\n");
}
void 乱数の種あり(void){    
    srand((unsigned int) time(NULL));//★乱数の種まき=seed設定
    for(int i = 0 ;i<10;i++){
        switch (rand() % 4)		{
        case 0: printf("風");   break;			    
        case 1: printf("林");   break;
        case 2: printf("火");   break;
        case 3: printf("山");   break;
        }
    }
    printf("<-種あり:実行する度に結果が変わる\n");
}
int main(void){
    乱数の種なし();
    乱数の種あり();
}

srand関数を使用して乱数の種を蒔かないと何度実行しても同じ結果になります。
乱数の種として現在時刻time(NULL)を使用するのが一般的です。


■乱数の種を蒔かないと毎回同じ結果

$ ./a.out
山火林山林山火風林林<-種なし:何回実行しても同じ結果になる
火火山火火山山山林山<-種あり:実行する度に結果が変わる
$ ./a.out
山火林山林山火風林林<-種なし:何回実行しても同じ結果になる
風山林火山風林風火林<-種あり:実行する度に結果が変わる
$ ./a.out
山火林山林山火風林林<-種なし:何回実行しても同じ結果になる
風山林火山風林風火林<-種あり:実行する度に結果が変わる
$ ./a.out
山火林山林山火風林林<-種なし:何回実行しても同じ結果になる
風山山風林林山風山風<-種あり:実行する度に結果が変わる
$

■じゃんけんプログラムの例

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
typedef enum {
    グー,チョキ,パー,    
} じゃんけん;
int main(void) {
    srand((unsigned int)time(NULL));
    for(int i = 1; i <= 10; i++) {
        printf("%d回目: ", i);
        じゃんけん  私      = rand() % 3;
        じゃんけん  貴方    = rand() % 3;
        switch(私){
        case グー:
            switch(貴方){
            case グー:     puts("引き分けGG");  break;
            case チョキ:   puts("私の勝ちGC");  break;
            case パー:     puts("私の負けGP");  break;
            }
            break; 
        case チョキ: 
            switch(貴方){
            case グー:     puts("私の負けCG");  break;
            case チョキ:   puts("引き分けCC");  break;
            case パー:     puts("私の勝ちCP");  break;
            }
            break;     
        case パー:  
            switch(貴方){
            case グー:     puts("私の勝ちPG");  break;
            case チョキ:   puts("私の負けPC");  break;
            case パー:     puts("引き分けPP");  break;
            }
            break;   
        }
    }
}

ここまで読んでいただいて恐縮ですが乱数を生成には
rand関数ではなくて
random関数のほうが良いそうです。
詳細は下記CERT-Cを参照ください。

参考:CERT-C MSC30-C. 疑似乱数の生成に rand() 関数を使用しない