6.乱数の生成と数字当てゲーム(rand関数、srand関数、time関数)

1. 乱数を生成する

1.1 ランド関数

関数のプロトタイプは次のとおりです。

int rand(void);

必要なヘッダー ファイル: stdlib.h

機能: 呼び出し後、ランダムに 1 つを返します擬似乱数、乱数の範囲は 0 ~ RAND_MAX で、ほとんどのコンパイラでは32767です(rand 関数は Ctrl+マウスの左ボタンで開き、#define RAND_MAX 0x7fffとして定義されます) 。

擬似乱数: 擬似乱数である理由は、 rand() 関数が「シード」と呼ばれる基準値に基づいて乱数を生成するためです。
シードについて: rand 関数のデフォルトのシード ベース値は 1 なので
、srand() 関数 (後述) を使用してシード ベース値を初期化する必要があります。

例:

#include <stdio.h>
#include <stdlib.h>
int main() {
    
    
	printf("%d\n", rand());
	printf("%d\n", rand());
	printf("%d\n", rand());
	return 0;
}

ここで rand 関数を 3 回呼び出した結果は次のとおりです:
41
18467
6334
それからプログラムを何度も再実行しましたが、乱数は変化しませんでした。常にこれらの数値でした。これが
ここで呼び出されるものです。 。擬似乱数したがって、乱数の実際の変更は、srand() 関数を呼び出して **シード** を変更することによって実現されます。

1.2 サンド関数

関数のプロトタイプは次のとおりです。

void srand(unsigned int seed);
srand() のパラメータは、非負の整数シードです
。この非負の整数シードは、いわゆるシードであり、rand() 関数によって返される乱数を決定します。

関数: 乱数ジェネレータを初期化する
この関数の本質: つまり、srand のシード (unsigned int シード) はランダムである必要があり、真の乱数を生成できるのは rand() 関数だけです。

質問: これは矛盾しているように聞こえますか?
rand() は乱数を生成するときにシードが乱数値である必要があります。srand
(seed) がシードを定義するときは、乱数値も必要です。rand の乱数はまだ生成されていません。乱数はどこから来るのでしょうか?

解決策: シード値が常に変化する限り、rand で毎回異なる関数を呼び出すことができるため、
次に time() 関数を使用する必要があります。

1.3倍機能

理由: 時刻は常に変化するため、プログラムが実行されている時刻をシードの初期値として使用します。

関数のプロトタイプは次のとおりです。

time_t 時間(time_t * タイマー);

必要なヘッダー ファイル: time.h

関数: time() 関数のパラメータが NULL の場合、現在の値を返します。タイムスタンプ; timer が NULL 以外のポインタの場合、関数は timer が指すメモリにタイムスタンプを置き、それを戻します。

タイムスタンプ: つまり、1970 年 1 月 1 日の 0:00:00 とプログラムの現在の実行時間との時間差です。単位は秒です。戻り値の型は time_t で、基本的に
long (32 ビット長の整数) またはlong long (64 ビット長整数)

例: 乱数を生成する

#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main() {
    
    
	//time()函数 参数为NULL时,返回当前时间戳,作为种子
	//因为srand函数的参数时unsigned int类型,所以将time函数的返回值类型强制转换
	unsigned int seed = (unsigned int)time(NULL);
	//初始化seed
	srand(seed);
	//调用rand() 并打印随机数
	printf("调用随机值(整型):%d\n", rand());
	return 0;
} 

結果: 時間が変化すると、生成される乱数は毎回異なります
注: srand 関数はプログラム内で 1 回呼び出すだけでよく、繰り返し呼び出す必要はありません。

1.4 乱数の範囲を設定する

例: 0 から 99 までの乱数を生成したい場合、方法は次のとおりです。

 rand() % 100;//余数的范围为0~99

原則:
rand() の戻り値の範囲は 0 ~ 32767 です。桁数で言えば、範囲は [10,000 秒 ~ 単位] です。
% 100 = この数値の下 2 桁です。例: 32699 % 100 = 99 32600 % 100 = 0
千の位レベルの数値 % 100 = この数値の最後の 2 桁の例: 3299 % 100 = 99 3200 % 100 = 0
百の位レベルの数値 % 100 = この数値の最後の 2 桁の例数値: 199 % 100 = 99 100 % 100 = 0、10
位の数値 % 100 = 数値そのもの 例: 99 % 100 = 99 0 % 100 = 0

上記の結論に基づいて、1 から 100 までの乱数を生成するには、次の方法があります。

 rand() % 100 + 1;//余数的范围为1~100



100から200までの乱数を生成するには、次の方法があります。

 100 + rand() % (200 - 100 + 1);//余数的范围为0~100,加100后就是100~200

要約:ab間の乱数を生成したい場合、方法は次のとおりです

a + rand() % (b - a + 1);

2. 数字当てゲーム

#define  _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void game() {
    
    
	int num = rand() % 100 + 1;//生成随机数(范围1-100)
	int guess = 0;//初始化 输入猜的数字
	int count = 5;//设置挑战次数

	while (count)
	{
    
    
		printf("你还有%d次机会,请输入你猜的数字:",count);
		scanf("%d", &guess);
		
		if (guess < num)
		{
    
    
			printf("猜小了\n");
			
		}
		else if (guess > num)
		{
    
    
			printf("猜大了\n");
		}
		else
		{
    
    
			printf("猜对了!\n");
			break;
		}
		count--;
	}
	if (count == 0)
	{
    
    
		printf("你失败了,正确答案是:%d\n",num);
	}
}

void menu() {
    
    

	printf("********************\n");
	printf("***  1.开始游戏  ***\n");
	printf("***  2.退出游戏  ***\n");
	printf("********************\n");
}

int main() {
    
    
	int input = 0;
	srand((unsigned int)time(NULL));//初始化种子,让rand()可以调用随机数
	do
	{
    
    
		menu();
		printf("请选择:");
		scanf("%d", &input);
		switch (input)
		{
    
    
		case 1:
			game();
			break;
		case 2:
			printf("游戏结束\n");

			//这里的break跳出的是switch结构,不用goto弹出游戏结束后还会继续循环菜单
			goto out;
			break;
		default:
			printf("选择错误,请重新选择\n");
			break;
		}
	} while (input);

	out:
	printf("成功退出游戏");
	return 0;
}

実行結果
ここに画像の説明を挿入します

おすすめ

転載: blog.csdn.net/qq_45657848/article/details/132005256